Tor 0.4.9.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"
61#include "core/or/circuitlist.h"
62#include "core/or/circuituse.h"
65#include "core/or/conflux.h"
67#include "core/or/crypt_path.h"
68#include "core/or/extendinfo.h"
69#include "core/or/status.h"
70#include "core/or/trace_probes_circuit.h"
72#include "app/config/config.h"
82#include "feature/hs/hs_cache.h"
85#include "feature/hs/hs_ident.h"
91#include "core/or/policies.h"
92#include "core/or/relay.h"
100#include "core/or/channelpadding.h"
105#include "lib/buf/buffers.h"
108#include "lib/math/stats.h"
109
110#include "core/or/ocirc_event.h"
111
112#include "ht.h"
113
118#include "core/or/half_edge_st.h"
120#include "core/or/or_circuit_st.h"
122
123#include "core/or/conflux_util.h"
124/********* START VARIABLES **********/
125
126/** A global list of all circuits at this hop. */
128
129/** A global list of all origin circuits. Every element of this is also
130 * an element of global_circuitlist. */
132
133/** A list of all the circuits in CIRCUIT_STATE_CHAN_WAIT. */
135
136/** List of all the (origin) circuits whose state is
137 * CIRCUIT_STATE_GUARD_WAIT. */
139
140/** A list of all the circuits that have been marked with
141 * circuit_mark_for_close and which are waiting for circuit_about_to_free. */
143
144static void circuit_about_to_free_atexit(circuit_t *circ);
145static void circuit_about_to_free(circuit_t *circ);
146
147/**
148 * A cached value of the current state of the origin circuit list. Has the
149 * value 1 if we saw any opened circuits recently (since the last call to
150 * circuit_any_opened_circuits(), which gets called around once a second by
151 * circuit_expire_building). 0 otherwise.
152 */
154
155/** Moving average of the cc->cwnd from each closed circuit. */
157/** Moving average of the cc->cwnd from each closed slow-start circuit. */
159
160uint64_t cc_stats_circs_closed = 0;
161
162/********* END VARIABLES ************/
163
164/* Implement circuit handle helpers. */
165HANDLE_IMPL(circuit, circuit_t,)
166
169{
170 tor_assert(x->magic == OR_CIRCUIT_MAGIC);
171 return DOWNCAST(or_circuit_t, x);
172}
173const or_circuit_t *
174CONST_TO_OR_CIRCUIT(const circuit_t *x)
175{
177 return DOWNCAST(or_circuit_t, x);
178}
181{
183 return DOWNCAST(origin_circuit_t, x);
184}
185const origin_circuit_t *
186CONST_TO_ORIGIN_CIRCUIT(const circuit_t *x)
187{
189 return DOWNCAST(origin_circuit_t, x);
190}
191
192/** A map from channel and circuit ID to circuit. (Lookup performance is
193 * very important here, since we need to do it every time a cell arrives.) */
195 HT_ENTRY(chan_circid_circuit_map_t) node;
196 channel_t *chan;
197 circid_t circ_id;
198 circuit_t *circuit;
199 /* For debugging 12184: when was this placeholder item added? */
200 time_t made_placeholder_at;
202
203/** Helper for hash tables: compare the channel and circuit ID for a and
204 * b, and return less than, equal to, or greater than zero appropriately.
205 */
206static inline int
209{
210 return a->chan == b->chan && a->circ_id == b->circ_id;
211}
212
213/** Helper: return a hash based on circuit ID and the pointer value of
214 * chan in <b>a</b>. */
215static inline unsigned int
217{
218 /* Try to squeze the siphash input into 8 bytes to save any extra siphash
219 * rounds. This hash function is in the critical path. */
220 uintptr_t chan = (uintptr_t) (void*) a->chan;
221 uint32_t array[2];
222 array[0] = a->circ_id;
223 /* The low bits of the channel pointer are uninteresting, since the channel
224 * is a pretty big structure. */
225 array[1] = (uint32_t) (chan >> 6);
226 return (unsigned) siphash24g(array, sizeof(array));
227}
228
229/** Map from [chan,circid] to circuit. */
230static HT_HEAD(chan_circid_map, chan_circid_circuit_map_t)
231 chan_circid_map = HT_INITIALIZER();
232HT_PROTOTYPE(chan_circid_map, chan_circid_circuit_map_t, node,
234HT_GENERATE2(chan_circid_map, chan_circid_circuit_map_t, node,
237
238/** The most recently returned entry from circuit_get_by_circid_chan;
239 * used to improve performance when many cells arrive in a row from the
240 * same circuit.
241 */
242static chan_circid_circuit_map_t *_last_circid_chan_ent = NULL;
243
244/** Implementation helper for circuit_set_{p,n}_circid_channel: A circuit ID
245 * and/or channel for circ has just changed from <b>old_chan, old_id</b>
246 * to <b>chan, id</b>. Adjust the chan,circid map as appropriate, removing
247 * the old entry (if any) and adding a new one. */
248static void
249circuit_set_circid_chan_helper(circuit_t *circ, int direction,
250 circid_t id,
251 channel_t *chan)
252{
255 channel_t *old_chan, **chan_ptr;
256 circid_t old_id, *circid_ptr;
257 int make_active, attached = 0;
258
259 if (direction == CELL_DIRECTION_OUT) {
260 chan_ptr = &circ->n_chan;
261 circid_ptr = &circ->n_circ_id;
262 make_active = circ->n_chan_cells.n > 0;
263 } else {
264 or_circuit_t *c = TO_OR_CIRCUIT(circ);
265 chan_ptr = &c->p_chan;
266 circid_ptr = &c->p_circ_id;
267 make_active = c->p_chan_cells.n > 0;
268 }
269 old_chan = *chan_ptr;
270 old_id = *circid_ptr;
271
272 if (id == old_id && chan == old_chan)
273 return;
274
275 if (_last_circid_chan_ent &&
276 ((old_id == _last_circid_chan_ent->circ_id &&
277 old_chan == _last_circid_chan_ent->chan) ||
278 (id == _last_circid_chan_ent->circ_id &&
279 chan == _last_circid_chan_ent->chan))) {
280 _last_circid_chan_ent = NULL;
281 }
282
283 if (old_chan) {
284 /*
285 * If we're changing channels or ID and had an old channel and a non
286 * zero old ID and weren't marked for close (i.e., we should have been
287 * attached), detach the circuit. ID changes require this because
288 * circuitmux hashes on (channel_id, circuit_id).
289 */
290 if (old_id != 0 && (old_chan != chan || old_id != id) &&
291 !(circ->marked_for_close)) {
292 tor_assert(old_chan->cmux);
293 circuitmux_detach_circuit(old_chan->cmux, circ);
294 }
295
296 /* we may need to remove it from the conn-circid map */
297 search.circ_id = old_id;
298 search.chan = old_chan;
299 found = HT_REMOVE(chan_circid_map, &chan_circid_map, &search);
300 if (found) {
301 tor_free(found);
302 if (direction == CELL_DIRECTION_OUT) {
303 /* One fewer circuits use old_chan as n_chan */
304 --(old_chan->num_n_circuits);
305 } else {
306 /* One fewer circuits use old_chan as p_chan */
307 --(old_chan->num_p_circuits);
308 }
309 }
310 }
311
312 /* Change the values only after we have possibly made the circuit inactive
313 * on the previous chan. */
314 *chan_ptr = chan;
315 *circid_ptr = id;
316
317 if (chan == NULL)
318 return;
319
320 /* now add the new one to the conn-circid map */
321 search.circ_id = id;
322 search.chan = chan;
323 found = HT_FIND(chan_circid_map, &chan_circid_map, &search);
324 if (found) {
325 found->circuit = circ;
326 found->made_placeholder_at = 0;
327 } else {
328 found = tor_malloc_zero(sizeof(chan_circid_circuit_map_t));
329 found->circ_id = id;
330 found->chan = chan;
331 found->circuit = circ;
332 HT_INSERT(chan_circid_map, &chan_circid_map, found);
333 }
334
335 /*
336 * Attach to the circuitmux if we're changing channels or IDs and
337 * have a new channel and ID to use and the circuit is not marked for
338 * close.
339 */
340 if (chan && id != 0 && (old_chan != chan || old_id != id) &&
341 !(circ->marked_for_close)) {
342 tor_assert(chan->cmux);
343 circuitmux_attach_circuit(chan->cmux, circ, direction);
344 attached = 1;
345 }
346
347 /*
348 * This is a no-op if we have no cells, but if we do it marks us active to
349 * the circuitmux
350 */
351 if (make_active && attached)
352 update_circuit_on_cmux(circ, direction);
353
354 /* Adjust circuit counts on new channel */
355 if (direction == CELL_DIRECTION_OUT) {
356 ++chan->num_n_circuits;
357 } else {
358 ++chan->num_p_circuits;
359 }
360}
361
362/** Mark that circuit id <b>id</b> shouldn't be used on channel <b>chan</b>,
363 * even if there is no circuit on the channel. We use this to keep the
364 * circuit id from getting re-used while we have queued but not yet sent
365 * a destroy cell. */
366void
368{
371
372 /* See if there's an entry there. That wouldn't be good. */
373 memset(&search, 0, sizeof(search));
374 search.chan = chan;
375 search.circ_id = id;
376 ent = HT_FIND(chan_circid_map, &chan_circid_map, &search);
377
378 if (ent && ent->circuit) {
379 /* we have a problem. */
380 log_warn(LD_BUG, "Tried to mark %u unusable on %p, but there was already "
381 "a circuit there.", (unsigned)id, chan);
382 } else if (ent) {
383 /* It's already marked. */
384 if (!ent->made_placeholder_at)
385 ent->made_placeholder_at = approx_time();
386 } else {
387 ent = tor_malloc_zero(sizeof(chan_circid_circuit_map_t));
388 ent->chan = chan;
389 ent->circ_id = id;
390 /* leave circuit at NULL. */
391 ent->made_placeholder_at = approx_time();
392 HT_INSERT(chan_circid_map, &chan_circid_map, ent);
393 }
394}
395
396/** Mark that a circuit id <b>id</b> can be used again on <b>chan</b>.
397 * We use this to re-enable the circuit ID after we've sent a destroy cell.
398 */
399void
401{
404
405 /* See if there's an entry there. That wouldn't be good. */
406 memset(&search, 0, sizeof(search));
407 search.chan = chan;
408 search.circ_id = id;
409 ent = HT_REMOVE(chan_circid_map, &chan_circid_map, &search);
410 if (ent && ent->circuit) {
411 log_warn(LD_BUG, "Tried to mark %u usable on %p, but there was already "
412 "a circuit there.", (unsigned)id, chan);
413 return;
414 }
415 if (_last_circid_chan_ent == ent)
416 _last_circid_chan_ent = NULL;
417 tor_free(ent);
418}
419
420/** Called to indicate that a DESTROY is pending on <b>chan</b> with
421 * circuit ID <b>id</b>, but hasn't been sent yet. */
422void
424{
426 if (circ) {
427 if (circ->n_chan == chan && circ->n_circ_id == id) {
428 circ->n_delete_pending = 1;
429 } else {
430 or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
431 if (orcirc->p_chan == chan && orcirc->p_circ_id == id) {
432 circ->p_delete_pending = 1;
433 }
434 }
435 return;
436 }
438}
439
440/** Called to indicate that a DESTROY is no longer pending on <b>chan</b> with
441 * circuit ID <b>id</b> -- typically, because it has been sent. */
442MOCK_IMPL(void,
444{
446 if (circ) {
447 if (circ->n_chan == chan && circ->n_circ_id == id) {
448 circ->n_delete_pending = 0;
449 } else {
450 or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
451 if (orcirc->p_chan == chan && orcirc->p_circ_id == id) {
452 circ->p_delete_pending = 0;
453 }
454 }
455 /* XXXX this shouldn't happen; log a bug here. */
456 return;
457 }
459}
460
461/** Set the p_conn field of a circuit <b>circ</b>, along
462 * with the corresponding circuit ID, and add the circuit as appropriate
463 * to the (chan,id)->circuit map. */
464void
466 channel_t *chan)
467{
468 circuit_t *circ = TO_CIRCUIT(or_circ);
469 channel_t *old_chan = or_circ->p_chan;
470 circid_t old_id = or_circ->p_circ_id;
471
472 circuit_set_circid_chan_helper(circ, CELL_DIRECTION_IN, id, chan);
473
474 if (chan) {
476 }
477
478 if (circ->p_delete_pending && old_chan) {
479 channel_mark_circid_unusable(old_chan, old_id);
480 circ->p_delete_pending = 0;
481 }
482}
483
484/** Set the n_conn field of a circuit <b>circ</b>, along
485 * with the corresponding circuit ID, and add the circuit as appropriate
486 * to the (chan,id)->circuit map. */
487void
489 channel_t *chan)
490{
491 channel_t *old_chan = circ->n_chan;
492 circid_t old_id = circ->n_circ_id;
493
494 circuit_set_circid_chan_helper(circ, CELL_DIRECTION_OUT, id, chan);
495
496 if (chan) {
498 }
499
500 if (circ->n_delete_pending && old_chan) {
501 channel_mark_circid_unusable(old_chan, old_id);
502 circ->n_delete_pending = 0;
503 }
504}
505
506/**
507 * Helper function to publish a message about events on an origin circuit
508 *
509 * Publishes a message to subscribers of origin circuit events, and
510 * sends the control event.
511 **/
512int
514 int reason_code)
515{
516 ocirc_cevent_msg_t *msg = tor_malloc(sizeof(*msg));
517
518 tor_assert(circ);
519
520 msg->gid = circ->global_identifier;
521 msg->evtype = tp;
522 msg->reason = reason_code;
523 msg->onehop = circ->build_state->onehop_tunnel;
524
525 ocirc_cevent_publish(msg);
526 return control_event_circuit_status(circ, tp, reason_code);
527}
528
529/**
530 * Helper function to publish a state change message
531 *
532 * circuit_set_state() calls this to notify subscribers about a change
533 * of the state of an origin circuit. @a circ must be an origin
534 * circuit.
535 **/
536static void
538{
539 ocirc_state_msg_t *msg = tor_malloc(sizeof(*msg));
540 const origin_circuit_t *ocirc;
541
543 ocirc = CONST_TO_ORIGIN_CIRCUIT(circ);
544 /* Only inbound OR circuits can be in this state, not origin circuits. */
546
547 msg->gid = ocirc->global_identifier;
548 msg->state = circ->state;
549 msg->onehop = ocirc->build_state->onehop_tunnel;
550
551 ocirc_state_publish(msg);
552}
553
554/** Change the state of <b>circ</b> to <b>state</b>, adding it to or removing
555 * it from lists as appropriate. */
556void
557circuit_set_state(circuit_t *circ, uint8_t state)
558{
559 tor_assert(circ);
560 if (state == circ->state)
561 return;
562 if (PREDICT_UNLIKELY(!circuits_pending_chans))
564 if (PREDICT_UNLIKELY(!circuits_pending_other_guards))
566 if (circ->state == CIRCUIT_STATE_CHAN_WAIT) {
567 /* remove from waiting-circuit list. */
569 }
570 if (state == CIRCUIT_STATE_CHAN_WAIT) {
571 /* add to waiting-circuit list. */
573 }
574 if (circ->state == CIRCUIT_STATE_GUARD_WAIT) {
576 }
577 if (state == CIRCUIT_STATE_GUARD_WAIT) {
579 }
580 if (state == CIRCUIT_STATE_GUARD_WAIT || state == CIRCUIT_STATE_OPEN)
582
583 tor_trace(TR_SUBSYS(circuit), TR_EV(change_state), circ, circ->state, state);
584 circ->state = state;
585 if (CIRCUIT_IS_ORIGIN(circ))
587}
588
589/** Append to <b>out</b> all circuits in state CHAN_WAIT waiting for
590 * the given connection. */
591void
593{
594 tor_assert(out);
595 tor_assert(chan);
596
598 return;
599
601 if (circ->marked_for_close)
602 continue;
603 if (!circ->n_hop)
604 continue;
607 /* Look at addr/port. This is an unkeyed connection. */
608 if (!channel_matches_extend_info(chan, circ->n_hop))
609 continue;
610 } else {
611 /* We expected a key. See if it's the right one. */
612 if (tor_memneq(chan->identity_digest,
614 continue;
615 }
616 smartlist_add(out, circ);
617 } SMARTLIST_FOREACH_END(circ);
618}
619
620/** Return the number of circuits in state CHAN_WAIT, waiting for the given
621 * channel. */
622int
624{
625 int cnt;
627
628 tor_assert(chan);
629
631 cnt = smartlist_len(sl);
632 smartlist_free(sl);
633 log_debug(LD_CIRC,"or_conn to %s, %d pending circs",
635 cnt);
636 return cnt;
637}
638
639/** Remove <b>origin_circ</b> from the global list of origin circuits.
640 * Called when we are freeing a circuit.
641 */
642static void
644{
645 int origin_idx = origin_circ->global_origin_circuit_list_idx;
646 if (origin_idx < 0)
647 return;
649 tor_assert(origin_idx <= smartlist_len(global_origin_circuit_list));
650 c2 = smartlist_get(global_origin_circuit_list, origin_idx);
651 tor_assert(origin_circ == c2);
653 if (origin_idx < smartlist_len(global_origin_circuit_list)) {
654 origin_circuit_t *replacement =
655 smartlist_get(global_origin_circuit_list, origin_idx);
656 replacement->global_origin_circuit_list_idx = origin_idx;
657 }
658 origin_circ->global_origin_circuit_list_idx = -1;
659}
660
661/** Add <b>origin_circ</b> to the global list of origin circuits. Called
662 * when creating the circuit. */
663static void
665{
666 tor_assert(origin_circ->global_origin_circuit_list_idx == -1);
668 smartlist_add(lst, origin_circ);
669 origin_circ->global_origin_circuit_list_idx = smartlist_len(lst) - 1;
670}
671
672/** Detach from the global circuit list, and deallocate, all
673 * circuits that have been marked for close.
674 */
675void
677{
678 if (circuits_pending_close == NULL)
679 return;
680
684
685 /* Remove it from the circuit list. */
686 int idx = circ->global_circuitlist_idx;
687 smartlist_del(lst, idx);
688 if (idx < smartlist_len(lst)) {
689 circuit_t *replacement = smartlist_get(lst, idx);
690 replacement->global_circuitlist_idx = idx;
691 }
692 circ->global_circuitlist_idx = -1;
693
694 /* Remove it from the origin circuit list, if appropriate. */
695 if (CIRCUIT_IS_ORIGIN(circ)) {
697 }
698
700 circuit_free(circ);
701 } SMARTLIST_FOREACH_END(circ);
702
704}
705
706/** Return a pointer to the global list of circuits. */
709{
710 if (NULL == global_circuitlist)
712 return global_circuitlist;
713}
714
715/** Return a pointer to the global list of origin circuits. */
718{
719 if (NULL == global_origin_circuit_list)
722}
723
724/**
725 * Return true if we have any opened general-purpose 3 hop
726 * origin circuits.
727 *
728 * The result from this function is cached for use by
729 * circuit_any_opened_circuits_cached().
730 */
731int
733{
735 const origin_circuit_t *, next_circ) {
736 if (!TO_CIRCUIT(next_circ)->marked_for_close &&
737 next_circ->has_opened &&
738 TO_CIRCUIT(next_circ)->state == CIRCUIT_STATE_OPEN &&
739 TO_CIRCUIT(next_circ)->purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT &&
740 next_circ->build_state &&
741 next_circ->build_state->desired_path_len == DEFAULT_ROUTE_LEN) {
743 return 1;
744 }
745 } SMARTLIST_FOREACH_END(next_circ);
746
748 return 0;
749}
750
751/**
752 * Cache the "any circuits opened" state, as specified in param
753 * circuits_are_opened. This is a helper function to update
754 * the circuit opened status whenever we happen to look at the
755 * circuit list.
756 */
757void
759{
760 any_opened_circs_cached_val = circuits_are_opened;
761}
762
763/**
764 * Return true if there were any opened circuits since the last call to
765 * circuit_any_opened_circuits(), or since circuit_expire_building() last
766 * ran (it runs roughly once per second).
767 */
768int
770{
772}
773
774/** Function to make circ->state human-readable */
775const char *
777{
778 static char buf[64];
779 switch (state) {
780 case CIRCUIT_STATE_BUILDING: return "doing handshakes";
781 case CIRCUIT_STATE_ONIONSKIN_PENDING: return "processing the onion";
782 case CIRCUIT_STATE_CHAN_WAIT: return "connecting to server";
783 case CIRCUIT_STATE_GUARD_WAIT: return "waiting to see how other "
784 "guards perform";
785 case CIRCUIT_STATE_OPEN: return "open";
786 default:
787 log_warn(LD_BUG, "Unknown circuit state %d", state);
788 tor_snprintf(buf, sizeof(buf), "unknown state [%d]", state);
789 return buf;
790 }
791}
792
793/** Map a circuit purpose to a string suitable to be displayed to a
794 * controller. */
795const char *
797{
798 static char buf[32];
799 switch (purpose) {
804 return "SERVER"; /* A controller should never see these, actually. */
805
807 return "GENERAL";
808
810 return "HS_CLIENT_HSDIR";
811
815 return "HS_CLIENT_INTRO";
816
821 return "HS_CLIENT_REND";
822
824 return "HS_SERVICE_HSDIR";
825
828 return "HS_SERVICE_INTRO";
829
832 return "HS_SERVICE_REND";
833
835 return "TESTING";
837 return "MEASURE_TIMEOUT";
839 return "CONTROLLER";
841 return "PATH_BIAS_TESTING";
843 return "HS_VANGUARDS";
845 return "CIRCUIT_PADDING";
846
848 return "CONFLUX_UNLINKED";
849 case CIRCUIT_PURPOSE_CONFLUX_LINKED:
850 return "CONFLUX_LINKED";
851
852 default:
853 tor_snprintf(buf, sizeof(buf), "UNKNOWN_%d", (int)purpose);
854 return buf;
855 }
856}
857
858/** Return a string specifying the state of the hidden-service circuit
859 * purpose <b>purpose</b>, or NULL if <b>purpose</b> is not a
860 * hidden-service-related circuit purpose. */
861const char *
863{
864 switch (purpose)
865 {
866 default:
868 "Unrecognized circuit purpose: %d",
869 (int)purpose);
872
882 case CIRCUIT_PURPOSE_CONFLUX_LINKED:
883 return NULL;
884
886 return "OR_HSSI_ESTABLISHED";
888 return "OR_HSCR_ESTABLISHED";
890 return "OR_HS_R_JOINED";
891
894 return "HSCI_CONNECTING";
896 return "HSCI_INTRO_SENT";
898 return "HSCI_DONE";
899
901 return "HSCR_CONNECTING";
903 return "HSCR_ESTABLISHED_IDLE";
905 return "HSCR_ESTABLISHED_WAITING";
907 return "HSCR_JOINED";
908
911 return "HSSI_CONNECTING";
913 return "HSSI_ESTABLISHED";
914
916 return "HSSR_CONNECTING";
918 return "HSSR_JOINED";
919 }
920}
921
922/** Return a human-readable string for the circuit purpose <b>purpose</b>. */
923const char *
925{
926 static char buf[32];
927
928 switch (purpose)
929 {
931 return "Circuit at relay";
933 return "Acting as intro point";
935 return "Acting as rendezvous (pending)";
937 return "Acting as rendezvous (established)";
939 return "General-purpose client";
941 return "Hidden service client: Connecting to intro point";
943 return "Hidden service client: Waiting for ack from intro point";
945 return "Hidden service client: Received ack from intro point";
947 return "Hidden service client: Establishing rendezvous point";
949 return "Hidden service client: Pending rendezvous point";
951 return "Hidden service client: Pending rendezvous point (ack received)";
953 return "Hidden service client: Active rendezvous point";
955 return "Hidden service client: Fetching HS descriptor";
956
958 return "Measuring circuit timeout";
959
961 return "Hidden service: Establishing introduction point";
963 return "Hidden service: Introduction point";
965 return "Hidden service: Connecting to rendezvous point";
967 return "Hidden service: Active rendezvous point";
969 return "Hidden service: Uploading HS descriptor";
970
972 return "Testing circuit";
973
975 return "Circuit made by controller";
976
978 return "Path-bias testing circuit";
979
981 return "Hidden service: Pre-built vanguard circuit";
982
984 return "Circuit kept open for padding";
985
987 return "Unlinked conflux circuit";
988
989 case CIRCUIT_PURPOSE_CONFLUX_LINKED:
990 return "Linked conflux circuit";
991
992 default:
993 tor_snprintf(buf, sizeof(buf), "UNKNOWN_%d", (int)purpose);
994 return buf;
995 }
996}
997
998/** Pick a reasonable package_window to start out for our circuits.
999 * Originally this was hard-coded at 1000, but now the consensus votes
1000 * on the answer. See proposal 168. */
1001int32_t
1003{
1004 int32_t num = networkstatus_get_param(NULL, "circwindow", CIRCWINDOW_START,
1005 CIRCWINDOW_START_MIN,
1006 CIRCWINDOW_START_MAX);
1007 /* If the consensus tells us a negative number, we'd assert. */
1008 if (num < 0)
1009 num = CIRCWINDOW_START;
1010 return num;
1011}
1012
1013/** Initialize the common elements in a circuit_t, and add it to the global
1014 * list. */
1015static void
1017{
1019
1020 // Gets reset when we send CREATE_FAST.
1021 // circuit_expire_building() expects these to be equal
1022 // until the orconn is built.
1023 circ->timestamp_began = circ->timestamp_created;
1024
1029
1031 circ->global_circuitlist_idx = smartlist_len(circuit_get_global_list()) - 1;
1032}
1033
1034/** If we haven't yet decided on a good timeout value for circuit
1035 * building, we close idle circuits aggressively so we can get more
1036 * data points. These are the default, min, and max consensus values */
1037#define DFLT_IDLE_TIMEOUT_WHILE_LEARNING (3*60)
1038#define MIN_IDLE_TIMEOUT_WHILE_LEARNING (10)
1039#define MAX_IDLE_TIMEOUT_WHILE_LEARNING (1000*60)
1040
1041/** Allocate space for a new circuit, initializing with <b>p_circ_id</b>
1042 * and <b>p_conn</b>. Add it to the global circuit list.
1043 */
1046{
1047 origin_circuit_t *circ;
1048 /* never zero, since a global ID of 0 is treated specially by the
1049 * controller */
1050 static uint32_t n_circuits_allocated = 1;
1051
1052 circ = tor_malloc_zero(sizeof(origin_circuit_t));
1053 circ->base_.magic = ORIGIN_CIRCUIT_MAGIC;
1054
1055 circ->next_stream_id = crypto_rand_int(1<<16);
1056 circ->global_identifier = n_circuits_allocated++;
1059
1061
1062 /* Add to origin-list. */
1065
1066 circuit_build_times_update_last_circ(get_circuit_build_times_mutable());
1067
1070 /* Circuits should be shorter lived if we need more of them
1071 * for learning a good build timeout */
1072 circ->circuit_idle_timeout =
1073 networkstatus_get_param(NULL, "cbtlearntimeout",
1075 MIN_IDLE_TIMEOUT_WHILE_LEARNING,
1076 MAX_IDLE_TIMEOUT_WHILE_LEARNING);
1077 } else {
1078 // This should always be larger than the current port prediction time
1079 // remaining, or else we'll end up with the case where a circuit times out
1080 // and another one is built, effectively doubling the timeout window.
1081 //
1082 // We also randomize it by up to 5% more (ie 5% of 0 to 3600 seconds,
1083 // depending on how much circuit prediction time is remaining) so that
1084 // we don't close a bunch of unused circuits all at the same time.
1085 int prediction_time_remaining =
1087 circ->circuit_idle_timeout = prediction_time_remaining+1+
1088 crypto_rand_int(1+prediction_time_remaining/20);
1089
1090 if (circ->circuit_idle_timeout <= 0) {
1091 log_warn(LD_BUG,
1092 "Circuit chose a negative idle timeout of %d based on "
1093 "%d seconds of predictive building remaining.",
1095 prediction_time_remaining);
1096 circ->circuit_idle_timeout =
1097 networkstatus_get_param(NULL, "cbtlearntimeout",
1099 MIN_IDLE_TIMEOUT_WHILE_LEARNING,
1100 MAX_IDLE_TIMEOUT_WHILE_LEARNING);
1101 }
1102
1103 log_info(LD_CIRC,
1104 "Circuit %"PRIu32" chose an idle timeout of %d based on "
1105 "%d seconds of predictive building remaining.",
1106 (circ->global_identifier),
1108 prediction_time_remaining);
1109 }
1110
1111 tor_trace(TR_SUBSYS(circuit), TR_EV(new_origin), circ);
1112 return circ;
1113}
1114
1115/** Allocate a new or_circuit_t, connected to <b>p_chan</b> as
1116 * <b>p_circ_id</b>. If <b>p_chan</b> is NULL, the circuit is unattached. */
1119{
1120 /* CircIDs */
1121 or_circuit_t *circ;
1122
1123 circ = tor_malloc_zero(sizeof(or_circuit_t));
1124 circ->base_.magic = OR_CIRCUIT_MAGIC;
1125
1126 if (p_chan)
1127 circuit_set_p_circid_chan(circ, p_circ_id, p_chan);
1128
1131
1133
1134 tor_trace(TR_SUBSYS(circuit), TR_EV(new_or), circ);
1135 return circ;
1136}
1137
1138/** Free all storage held in circ->testing_cell_stats */
1139void
1141{
1142 if (!circ || !circ->testing_cell_stats)
1143 return;
1145 ent, tor_free(ent));
1146 smartlist_free(circ->testing_cell_stats);
1147 circ->testing_cell_stats = NULL;
1148}
1149
1150/** Deallocate space associated with circ.
1151 */
1152STATIC void
1154{
1155 circid_t n_circ_id = 0;
1156 void *mem;
1157 size_t memlen;
1158 int should_free = 1;
1159 if (!circ)
1160 return;
1161
1162 /* We keep a copy of this so we can log its value before it gets unset. */
1163 n_circ_id = circ->n_circ_id;
1164
1166
1167 /* Cleanup circuit from anything HS v3 related. We also do this when the
1168 * circuit is closed. This is to avoid any code path that free registered
1169 * circuits without closing them before. This needs to be done before the
1170 * hs identifier is freed. */
1172
1174
1175 if (CIRCUIT_IS_ORIGIN(circ)) {
1176 origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
1177 mem = ocirc;
1178 memlen = sizeof(origin_circuit_t);
1180
1182
1183 if (ocirc->half_streams) {
1185 half_conn) {
1186 half_edge_free(half_conn);
1187 } SMARTLIST_FOREACH_END(half_conn);
1188 smartlist_free(ocirc->half_streams);
1189 }
1190
1191 if (ocirc->build_state) {
1192 extend_info_free(ocirc->build_state->chosen_exit);
1193 }
1194 tor_free(ocirc->build_state);
1195
1196 /* Cancel before freeing, if we haven't already succeeded or failed. */
1197 if (ocirc->guard_state) {
1199 }
1200 circuit_guard_state_free(ocirc->guard_state);
1201
1202 circuit_clear_cpath(ocirc);
1203
1204 crypto_pk_free(ocirc->intro_key);
1205
1206 /* Finally, free the identifier of the circuit and nullify it so multiple
1207 * cleanup will work. */
1208 hs_ident_circuit_free(ocirc->hs_ident);
1209 ocirc->hs_ident = NULL;
1210
1211 tor_free(ocirc->dest_address);
1212 if (ocirc->socks_username) {
1213 memwipe(ocirc->socks_username, 0x12, ocirc->socks_username_len);
1214 tor_free(ocirc->socks_username);
1215 }
1216 if (ocirc->socks_password) {
1217 memwipe(ocirc->socks_password, 0x06, ocirc->socks_password_len);
1218 tor_free(ocirc->socks_password);
1219 }
1220 addr_policy_list_free(ocirc->prepend_policy);
1221 } else {
1222 or_circuit_t *ocirc = TO_OR_CIRCUIT(circ);
1223 /* Remember cell statistics for this circuit before deallocating. */
1224 if (get_options()->CellStatistics)
1225 rep_hist_buffer_stats_add_circ(circ, time(NULL));
1226 mem = ocirc;
1227 memlen = sizeof(or_circuit_t);
1229
1230 should_free = (ocirc->workqueue_entry == NULL);
1231
1232 relay_crypto_clear(&ocirc->crypto);
1233
1234 if (ocirc->rend_splice) {
1235 or_circuit_t *other = ocirc->rend_splice;
1236 tor_assert(other->base_.magic == OR_CIRCUIT_MAGIC);
1237 other->rend_splice = NULL;
1238 }
1239
1240 /* remove from map. */
1241 circuit_set_p_circid_chan(ocirc, 0, NULL);
1242
1243 /* Clear cell queue _after_ removing it from the map. Otherwise our
1244 * "active" checks will be violated. */
1246 }
1247
1248 extend_info_free(circ->n_hop);
1250
1251 if (circ->global_circuitlist_idx != -1) {
1252 int idx = circ->global_circuitlist_idx;
1253 circuit_t *c2 = smartlist_get(global_circuitlist, idx);
1254 tor_assert(c2 == circ);
1256 if (idx < smartlist_len(global_circuitlist)) {
1257 c2 = smartlist_get(global_circuitlist, idx);
1258 c2->global_circuitlist_idx = idx;
1259 }
1260 }
1261
1262 /* Remove from map. */
1263 circuit_set_n_circid_chan(circ, 0, NULL);
1264
1265 /* Clear cell queue _after_ removing it from the map. Otherwise our
1266 * "active" checks will be violated. */
1268
1269 /* Cleanup possible SENDME state. */
1270 if (circ->sendme_last_digests) {
1271 SMARTLIST_FOREACH(circ->sendme_last_digests, uint8_t *, d, tor_free(d));
1272 smartlist_free(circ->sendme_last_digests);
1273 }
1274
1275 log_info(LD_CIRC, "Circuit %u (id: %" PRIu32 ") has been freed.",
1276 n_circ_id,
1277 CIRCUIT_IS_ORIGIN(circ) ?
1278 TO_ORIGIN_CIRCUIT(circ)->global_identifier : 0);
1279
1280 /* Free any circuit padding structures */
1282
1283 /* Clear all dangling handle references. */
1284 circuit_handles_clear(circ);
1285
1286 /* Tracepoint. Data within the circuit object is recorded so do this before
1287 * the actual memory free. */
1288 tor_trace(TR_SUBSYS(circuit), TR_EV(free), circ);
1289
1290 if (should_free) {
1291 memwipe(mem, 0xAA, memlen); /* poison memory */
1292 tor_free(mem);
1293 } else {
1294 /* If we made it here, this is an or_circuit_t that still has a pending
1295 * cpuworker request which we weren't able to cancel. Instead, set up
1296 * the magic value so that when the reply comes back, we'll know to discard
1297 * the reply and free this structure.
1298 */
1299 memwipe(mem, 0xAA, memlen);
1300 circ->magic = DEAD_CIRCUIT_MAGIC;
1301 }
1302}
1303
1304/** Deallocate the linked list circ-><b>cpath</b>, and remove the cpath from
1305 * <b>circ</b>. */
1306void
1308{
1309 crypt_path_t *victim, *head, *cpath;
1310
1311 head = cpath = circ->cpath;
1312
1313 if (!cpath)
1314 return;
1315
1316 /* it's a circular list, so we have to notice when we've
1317 * gone through it once. */
1318 while (cpath->next && cpath->next != head) {
1319 victim = cpath;
1320 cpath = victim->next;
1321 cpath_free(victim);
1322 }
1323
1324 cpath_free(cpath);
1325
1326 circ->cpath = NULL;
1327}
1328
1329/** Release all storage held by circuits. */
1330void
1332{
1334
1335 SMARTLIST_FOREACH_BEGIN(lst, circuit_t *, tmp) {
1336 if (! CIRCUIT_IS_ORIGIN(tmp)) {
1337 or_circuit_t *or_circ = TO_OR_CIRCUIT(tmp);
1338 while (or_circ->resolving_streams) {
1339 edge_connection_t *next_conn;
1340 next_conn = or_circ->resolving_streams->next_stream;
1342 or_circ->resolving_streams = next_conn;
1343 }
1344 }
1345 tmp->global_circuitlist_idx = -1;
1347 circuit_free(tmp);
1348 SMARTLIST_DEL_CURRENT(lst, tmp);
1349 } SMARTLIST_FOREACH_END(tmp);
1350
1351 smartlist_free(lst);
1352 global_circuitlist = NULL;
1353
1354 smartlist_free(global_origin_circuit_list);
1356
1357 smartlist_free(circuits_pending_chans);
1359
1360 smartlist_free(circuits_pending_close);
1362
1363 smartlist_free(circuits_pending_other_guards);
1365
1366 {
1367 chan_circid_circuit_map_t **elt, **next, *c;
1368 for (elt = HT_START(chan_circid_map, &chan_circid_map);
1369 elt;
1370 elt = next) {
1371 c = *elt;
1372 next = HT_NEXT_RMV(chan_circid_map, &chan_circid_map, elt);
1373
1374 tor_assert(c->circuit == NULL);
1375 tor_free(c);
1376 }
1377 }
1378 HT_CLEAR(chan_circid_map, &chan_circid_map);
1379}
1380
1381/** A helper function for circuit_dump_by_conn() below. Log a bunch
1382 * of information about circuit <b>circ</b>.
1383 */
1384static void
1386 circuit_t *circ,
1387 int conn_array_index,
1388 const char *type,
1389 circid_t this_circid,
1390 circid_t other_circid)
1391{
1392 tor_log(severity, LD_CIRC, "Conn %d has %s circuit: circID %u "
1393 "(other side %u), state %d (%s), born %ld:",
1394 conn_array_index, type, (unsigned)this_circid, (unsigned)other_circid,
1395 circ->state, circuit_state_to_string(circ->state),
1396 (long)circ->timestamp_began.tv_sec);
1397 if (CIRCUIT_IS_ORIGIN(circ)) { /* circ starts at this node */
1398 circuit_log_path(severity, LD_CIRC, TO_ORIGIN_CIRCUIT(circ));
1399 }
1400}
1401
1402/** Log, at severity <b>severity</b>, information about each circuit
1403 * that is connected to <b>conn</b>.
1404 */
1405void
1407{
1408 edge_connection_t *tmpconn;
1409
1411 circid_t n_circ_id = circ->n_circ_id, p_circ_id = 0;
1412
1413 if (circ->marked_for_close) {
1414 continue;
1415 }
1416
1417 if (!CIRCUIT_IS_ORIGIN(circ)) {
1418 p_circ_id = TO_OR_CIRCUIT(circ)->p_circ_id;
1419 }
1420
1421 if (CIRCUIT_IS_ORIGIN(circ)) {
1422 for (tmpconn=TO_ORIGIN_CIRCUIT(circ)->p_streams; tmpconn;
1423 tmpconn=tmpconn->next_stream) {
1424 if (TO_CONN(tmpconn) == conn) {
1425 circuit_dump_conn_details(severity, circ, conn->conn_array_index,
1426 "App-ward", p_circ_id, n_circ_id);
1427 }
1428 }
1429 }
1430
1431 if (! CIRCUIT_IS_ORIGIN(circ)) {
1432 for (tmpconn=TO_OR_CIRCUIT(circ)->n_streams; tmpconn;
1433 tmpconn=tmpconn->next_stream) {
1434 if (TO_CONN(tmpconn) == conn) {
1435 circuit_dump_conn_details(severity, circ, conn->conn_array_index,
1436 "Exit-ward", n_circ_id, p_circ_id);
1437 }
1438 }
1439 }
1440 }
1441 SMARTLIST_FOREACH_END(circ);
1442}
1443
1444/** Return the circuit whose global ID is <b>id</b>, or NULL if no
1445 * such circuit exists. */
1448{
1450 if (CIRCUIT_IS_ORIGIN(circ) &&
1451 TO_ORIGIN_CIRCUIT(circ)->global_identifier == id) {
1452 if (circ->marked_for_close)
1453 return NULL;
1454 else
1455 return TO_ORIGIN_CIRCUIT(circ);
1456 }
1457 }
1458 SMARTLIST_FOREACH_END(circ);
1459 return NULL;
1460}
1461
1462/** Return a circ such that:
1463 * - circ->n_circ_id or circ->p_circ_id is equal to <b>circ_id</b>, and
1464 * - circ is attached to <b>chan</b>, either as p_chan or n_chan.
1465 * Return NULL if no such circuit exists.
1466 *
1467 * If <b>found_entry_out</b> is provided, set it to true if we have a
1468 * placeholder entry for circid/chan, and leave it unset otherwise.
1469 */
1470static inline circuit_t *
1472 int *found_entry_out)
1473{
1476
1477 if (_last_circid_chan_ent &&
1478 circ_id == _last_circid_chan_ent->circ_id &&
1479 chan == _last_circid_chan_ent->chan) {
1480 found = _last_circid_chan_ent;
1481 } else {
1482 search.circ_id = circ_id;
1483 search.chan = chan;
1484 found = HT_FIND(chan_circid_map, &chan_circid_map, &search);
1485 _last_circid_chan_ent = found;
1486 }
1487 if (found && found->circuit) {
1488 log_debug(LD_CIRC,
1489 "circuit_get_by_circid_channel_impl() returning circuit %p for"
1490 " circ_id %u, channel ID %"PRIu64 " (%p)",
1491 found->circuit, (unsigned)circ_id,
1492 (chan->global_identifier), chan);
1493 if (found_entry_out)
1494 *found_entry_out = 1;
1495 return found->circuit;
1496 }
1497
1498 log_debug(LD_CIRC,
1499 "circuit_get_by_circid_channel_impl() found %s for"
1500 " circ_id %u, channel ID %"PRIu64 " (%p)",
1501 found ? "placeholder" : "nothing",
1502 (unsigned)circ_id,
1503 (chan->global_identifier), chan);
1504
1505 if (found_entry_out)
1506 *found_entry_out = found ? 1 : 0;
1507
1508 return NULL;
1509 /* The rest of this checks for bugs. Disabled by default. */
1510 /* We comment it out because coverity complains otherwise.
1511 {
1512 circuit_t *circ;
1513 TOR_LIST_FOREACH(circ, &global_circuitlist, head) {
1514 if (! CIRCUIT_IS_ORIGIN(circ)) {
1515 or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
1516 if (or_circ->p_chan == chan && or_circ->p_circ_id == circ_id) {
1517 log_warn(LD_BUG,
1518 "circuit matches p_chan, but not in hash table (Bug!)");
1519 return circ;
1520 }
1521 }
1522 if (circ->n_chan == chan && circ->n_circ_id == circ_id) {
1523 log_warn(LD_BUG,
1524 "circuit matches n_chan, but not in hash table (Bug!)");
1525 return circ;
1526 }
1527 }
1528 return NULL;
1529 } */
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 * - circ is not marked for close.
1536 * Return NULL if no such circuit exists.
1537 */
1538circuit_t *
1540{
1541 circuit_t *circ = circuit_get_by_circid_channel_impl(circ_id, chan, NULL);
1542 if (!circ || circ->marked_for_close)
1543 return NULL;
1544 else
1545 return circ;
1546}
1547
1548/** Return a circ such that:
1549 * - circ->n_circ_id or circ->p_circ_id is equal to <b>circ_id</b>, and
1550 * - circ is attached to <b>chan</b>, either as p_chan or n_chan.
1551 * Return NULL if no such circuit exists.
1552 */
1553circuit_t *
1555 channel_t *chan)
1556{
1557 return circuit_get_by_circid_channel_impl(circ_id, chan, NULL);
1558}
1559
1560/** Return true iff the circuit ID <b>circ_id</b> is currently used by a
1561 * circuit, marked or not, on <b>chan</b>, or if the circ ID is reserved until
1562 * a queued destroy cell can be sent.
1563 *
1564 * (Return 1 if the circuit is present, marked or not; Return 2
1565 * if the circuit ID is pending a destroy.)
1566 **/
1567int
1569{
1570 int found = 0;
1571 if (circuit_get_by_circid_channel_impl(circ_id, chan, &found) != NULL)
1572 return 1;
1573 if (found)
1574 return 2;
1575 return 0;
1576}
1577
1578/** Helper for debugging 12184. Returns the time since which 'circ_id' has
1579 * been marked unusable on 'chan'. */
1580time_t
1582{
1585
1586 memset(&search, 0, sizeof(search));
1587 search.circ_id = circ_id;
1588 search.chan = chan;
1589
1590 found = HT_FIND(chan_circid_map, &chan_circid_map, &search);
1591
1592 if (! found || found->circuit)
1593 return 0;
1594
1595 return found->made_placeholder_at;
1596}
1597
1598/** Return the circuit that a given edge connection is using. */
1599circuit_t *
1601{
1602 circuit_t *circ;
1603
1604 circ = conn->on_circuit;
1605 tor_assert(!circ ||
1607 : circ->magic == OR_CIRCUIT_MAGIC));
1608
1609 return circ;
1610}
1611
1612/** For each circuit that has <b>chan</b> as n_chan or p_chan, unlink the
1613 * circuit from the chan,circid map, and mark it for close if it hasn't
1614 * been marked already.
1615 */
1616void
1618{
1619 smartlist_t *detached = smartlist_new();
1620
1621/* #define DEBUG_CIRCUIT_UNLINK_ALL */
1622
1623 channel_unlink_all_circuits(chan, detached);
1624
1625#ifdef DEBUG_CIRCUIT_UNLINK_ALL
1626 {
1627 smartlist_t *detached_2 = smartlist_new();
1628 int mismatch = 0, badlen = 0;
1629
1631 if (circ->n_chan == chan ||
1632 (!CIRCUIT_IS_ORIGIN(circ) &&
1633 TO_OR_CIRCUIT(circ)->p_chan == chan)) {
1634 smartlist_add(detached_2, circ);
1635 }
1636 }
1637 SMARTLIST_FOREACH_END(circ);
1638
1639 if (smartlist_len(detached) != smartlist_len(detached_2)) {
1640 log_warn(LD_BUG, "List of detached circuits had the wrong length! "
1641 "(got %d, should have gotten %d)",
1642 (int)smartlist_len(detached),
1643 (int)smartlist_len(detached_2));
1644 badlen = 1;
1645 }
1646 smartlist_sort_pointers(detached);
1647 smartlist_sort_pointers(detached_2);
1648
1649 SMARTLIST_FOREACH(detached, circuit_t *, c,
1650 if (c != smartlist_get(detached_2, c_sl_idx))
1651 mismatch = 1;
1652 );
1653
1654 if (mismatch)
1655 log_warn(LD_BUG, "Mismatch in list of detached circuits.");
1656
1657 if (badlen || mismatch) {
1658 smartlist_free(detached);
1659 detached = detached_2;
1660 } else {
1661 log_notice(LD_CIRC, "List of %d circuits was as expected.",
1662 (int)smartlist_len(detached));
1663 smartlist_free(detached_2);
1664 }
1665 }
1666#endif /* defined(DEBUG_CIRCUIT_UNLINK_ALL) */
1667
1668 SMARTLIST_FOREACH_BEGIN(detached, circuit_t *, circ) {
1669 int mark = 0;
1670 if (circ->n_chan == chan) {
1671
1672 circuit_set_n_circid_chan(circ, 0, NULL);
1673 mark = 1;
1674
1675 /* If we didn't request this closure, pass the remote
1676 * bit to mark_for_close. */
1677 if (chan->reason_for_closing != CHANNEL_CLOSE_REQUESTED)
1679 }
1680 if (! CIRCUIT_IS_ORIGIN(circ)) {
1681 or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
1682 if (or_circ->p_chan == chan) {
1683 circuit_set_p_circid_chan(or_circ, 0, NULL);
1684 mark = 1;
1685 }
1686 }
1687 if (!mark) {
1688 log_warn(LD_BUG, "Circuit on detached list which I had no reason "
1689 "to mark");
1690 continue;
1691 }
1692 if (!circ->marked_for_close)
1693 circuit_mark_for_close(circ, reason);
1694 } SMARTLIST_FOREACH_END(circ);
1695
1696 smartlist_free(detached);
1697}
1698
1699/** Return the first introduction circuit originating from the global circuit
1700 * list after <b>start</b> or at the start of the list if <b>start</b> is
1701 * NULL. Return NULL if no circuit is found.
1702 *
1703 * If <b>want_client_circ</b> is true, then we are looking for client-side
1704 * introduction circuits: A client introduction point circuit has a purpose of
1705 * either CIRCUIT_PURPOSE_C_INTRODUCING, CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT
1706 * or CIRCUIT_PURPOSE_C_INTRODUCE_ACKED. This does not return a circuit marked
1707 * for close, but it returns circuits regardless of their circuit state.
1708 *
1709 * If <b>want_client_circ</b> is false, then we are looking for service-side
1710 * introduction circuits: A service introduction point circuit has a purpose of
1711 * either CIRCUIT_PURPOSE_S_ESTABLISH_INTRO or CIRCUIT_PURPOSE_S_INTRO. This
1712 * does not return circuits marked for close, or in any state other than open.
1713 */
1716 bool want_client_circ)
1717{
1718 int idx = 0;
1720
1721 if (start) {
1722 idx = TO_CIRCUIT(start)->global_circuitlist_idx + 1;
1723 }
1724
1725 for ( ; idx < smartlist_len(lst); ++idx) {
1726 circuit_t *circ = smartlist_get(lst, idx);
1727
1728 /* Ignore a marked for close circuit or if the state is not open. */
1729 if (circ->marked_for_close) {
1730 continue;
1731 }
1732
1733 /* Depending on whether we are looking for client or service circs, skip
1734 * circuits with other purposes. */
1735 if (want_client_circ) {
1739 continue;
1740 }
1741 } else { /* we are looking for service-side circs */
1742 if (circ->state != CIRCUIT_STATE_OPEN) {
1743 continue;
1744 }
1747 continue;
1748 }
1749 }
1750
1751 /* The purposes we are looking for are only for origin circuits so the
1752 * following is valid. */
1753 return TO_ORIGIN_CIRCUIT(circ);
1754 }
1755 /* Not found. */
1756 return NULL;
1757}
1758
1759/** Return the first service rendezvous circuit originating from the global
1760 * circuit list after <b>start</b> or at the start of the list if <b>start</b>
1761 * is NULL. Return NULL if no circuit is found.
1762 *
1763 * A service rendezvous point circuit has a purpose of either
1764 * CIRCUIT_PURPOSE_S_CONNECT_REND or CIRCUIT_PURPOSE_S_REND_JOINED. This does
1765 * not return a circuit marked for close and its state must be open. */
1768{
1769 int idx = 0;
1771
1772 if (start) {
1773 idx = TO_CIRCUIT(start)->global_circuitlist_idx + 1;
1774 }
1775
1776 for ( ; idx < smartlist_len(lst); ++idx) {
1777 circuit_t *circ = smartlist_get(lst, idx);
1778
1779 /* Ignore a marked for close circuit or purpose not matching a service
1780 * intro point or if the state is not open. */
1781 if (circ->marked_for_close || circ->state != CIRCUIT_STATE_OPEN ||
1784 continue;
1785 }
1786 /* The purposes we are looking for are only for origin circuits so the
1787 * following is valid. */
1788 return TO_ORIGIN_CIRCUIT(circ);
1789 }
1790 /* Not found. */
1791 return NULL;
1792}
1793
1794/** Return the first circuit originating here in global_circuitlist after
1795 * <b>start</b> whose purpose is <b>purpose</b>. Return NULL if no circuit is
1796 * found. If <b>start</b> is NULL, begin at the start of the list. */
1799{
1800 int idx;
1803 if (start == NULL)
1804 idx = 0;
1805 else
1806 idx = TO_CIRCUIT(start)->global_circuitlist_idx + 1;
1807
1808 for ( ; idx < smartlist_len(lst); ++idx) {
1809 circuit_t *circ = smartlist_get(lst, idx);
1810
1811 if (circ->marked_for_close)
1812 continue;
1813 if (circ->purpose != purpose)
1814 continue;
1815 /* At this point we should be able to get a valid origin circuit because
1816 * the origin purpose we are looking for matches this circuit. */
1817 if (BUG(!CIRCUIT_PURPOSE_IS_ORIGIN(circ->purpose))) {
1818 break;
1819 }
1820 return TO_ORIGIN_CIRCUIT(circ);
1821 }
1822 return NULL;
1823}
1824
1825/** We might cannibalize this circuit: Return true if its last hop can be used
1826 * as a v3 rendezvous point. */
1827static int
1829{
1830 if (!circ->build_state) {
1831 return 0;
1832 }
1833
1834 extend_info_t *chosen_exit = circ->build_state->chosen_exit;
1835 if (BUG(!chosen_exit)) {
1836 return 0;
1837 }
1838
1839 const node_t *rp_node = node_get_by_id(chosen_exit->identity_digest);
1840 if (rp_node) {
1841 if (node_supports_v3_rendezvous_point(rp_node)) {
1842 return 1;
1843 }
1844 }
1845
1846 return 0;
1847}
1848
1849/** We are trying to create a circuit of purpose <b>purpose</b> and we are
1850 * looking for cannibalizable circuits. Return the circuit purpose we would be
1851 * willing to cannibalize. */
1852static uint8_t
1854{
1855 if (circuit_should_use_vanguards(purpose)) {
1856 /* If we are using vanguards, then we should only cannibalize vanguard
1857 * circuits so that we get the same path construction logic. */
1859 } else {
1860 /* Conflux purposes should never get here */
1861 tor_assert_nonfatal(purpose != CIRCUIT_PURPOSE_CONFLUX_UNLINKED &&
1862 purpose != CIRCUIT_PURPOSE_CONFLUX_LINKED);
1863 /* If no vanguards are used just get a general circuit! */
1865 }
1866}
1867
1868/** Return a circuit that is open, is CIRCUIT_PURPOSE_C_GENERAL,
1869 * has a timestamp_dirty value of 0, has flags matching the CIRCLAUNCH_*
1870 * flags in <b>flags</b>, and if info is defined, does not already use info
1871 * as any of its hops; or NULL if no circuit fits this description.
1872 *
1873 * The <b>purpose</b> argument refers to the purpose of the circuit we want to
1874 * create, not the purpose of the circuit we want to cannibalize.
1875 *
1876 * If !CIRCLAUNCH_NEED_UPTIME, prefer returning non-uptime circuits.
1877 *
1878 * To "cannibalize" a circuit means to extend it an extra hop, and use it
1879 * for some other purpose than we had originally intended. We do this when
1880 * we want to perform some low-bandwidth task at a specific relay, and we
1881 * would like the circuit to complete as soon as possible. (If we were going
1882 * to use a lot of bandwidth, we wouldn't want a circuit with an extra hop.
1883 * If we didn't care about circuit completion latency, we would just build
1884 * a new circuit.)
1885 */
1887circuit_find_to_cannibalize(uint8_t purpose_to_produce, extend_info_t *info,
1888 int flags)
1889{
1890 origin_circuit_t *best=NULL;
1891 int need_uptime = (flags & CIRCLAUNCH_NEED_UPTIME) != 0;
1892 int need_capacity = (flags & CIRCLAUNCH_NEED_CAPACITY) != 0;
1893 int internal = (flags & CIRCLAUNCH_IS_INTERNAL) != 0;
1894 const or_options_t *options = get_options();
1895 /* We want the circuit we are trying to cannibalize to have this purpose */
1896 int purpose_to_search_for;
1897
1898 /* Make sure we're not trying to create a onehop circ by
1899 * cannibalization. */
1901
1902 purpose_to_search_for = get_circuit_purpose_needed_to_cannibalize(
1903 purpose_to_produce);
1904
1905 tor_assert_nonfatal(purpose_to_search_for == CIRCUIT_PURPOSE_C_GENERAL ||
1906 purpose_to_search_for == CIRCUIT_PURPOSE_HS_VANGUARDS);
1907
1908 tor_assert_nonfatal(purpose_to_search_for !=
1910 tor_assert_nonfatal(purpose_to_produce != CIRCUIT_PURPOSE_CONFLUX_UNLINKED);
1911
1912 log_debug(LD_CIRC,
1913 "Hunting for a circ to cannibalize: purpose %d, uptime %d, "
1914 "capacity %d, internal %d",
1915 purpose_to_produce, need_uptime, need_capacity, internal);
1916
1918 if (CIRCUIT_IS_ORIGIN(circ_) &&
1919 circ_->state == CIRCUIT_STATE_OPEN &&
1920 !circ_->marked_for_close &&
1921 circ_->purpose == purpose_to_search_for &&
1922 !circ_->timestamp_dirty) {
1923 origin_circuit_t *circ = TO_ORIGIN_CIRCUIT(circ_);
1924
1925 /* Only cannibalize from reasonable length circuits. If we
1926 * want C_GENERAL, then only choose 3 hop circs. If we want
1927 * HS_VANGUARDS, only choose 4 hop circs.
1928 */
1929 if (circ->build_state->desired_path_len !=
1930 route_len_for_purpose(purpose_to_search_for, NULL)) {
1931 goto next;
1932 }
1933
1934 /* Ignore any circuits for which we can't use the Guard. It is possible
1935 * that the Guard was removed from the sampled set after the circuit
1936 * was created, so avoid using it. */
1938 goto next;
1939 }
1940
1941 if ((!need_uptime || circ->build_state->need_uptime) &&
1942 (!need_capacity || circ->build_state->need_capacity) &&
1943 (internal == circ->build_state->is_internal) &&
1944 !circ->unusable_for_new_conns &&
1946 !circ->build_state->onehop_tunnel &&
1947 !circ->isolation_values_set) {
1948 if (info) {
1949 /* need to make sure we don't duplicate hops */
1950 crypt_path_t *hop = circ->cpath;
1951 const node_t *ri1 = node_get_by_id(info->identity_digest);
1952 do {
1953 const node_t *ri2;
1956 goto next;
1957 if (ri1 &&
1959 && nodes_in_same_family(ri1, ri2))
1960 goto next;
1961 hop=hop->next;
1962 } while (hop!=circ->cpath);
1963 }
1964 if (options->ExcludeNodes) {
1965 /* Make sure no existing nodes in the circuit are excluded for
1966 * general use. (This may be possible if StrictNodes is 0, and we
1967 * thought we needed to use an otherwise excluded node for, say, a
1968 * directory operation.) */
1969 crypt_path_t *hop = circ->cpath;
1970 do {
1972 hop->extend_info))
1973 goto next;
1974 hop = hop->next;
1975 } while (hop != circ->cpath);
1976 }
1977
1978 if ((flags & CIRCLAUNCH_IS_V3_RP) &&
1980 log_debug(LD_GENERAL, "Skipping uncannibalizable circuit for v3 "
1981 "rendezvous point.");
1982 goto next;
1983 }
1984
1985 if (!best || (best->build_state->need_uptime && !need_uptime))
1986 best = circ;
1987 next: ;
1988 }
1989 }
1990 }
1991 SMARTLIST_FOREACH_END(circ_);
1992 return best;
1993}
1994
1995/**
1996 * Check whether any of the origin circuits that are waiting to see if
1997 * their guard is good enough to use can be upgraded to "ready". If so,
1998 * return a new smartlist containing them. Otherwise return NULL.
1999 */
2002{
2003 /* Only if some circuit is actually waiting on an upgrade should we
2004 * run the algorithm. */
2006 smartlist_len(circuits_pending_other_guards)==0)
2007 return NULL;
2008 /* Only if we have some origin circuits should we run the algorithm. */
2010 return NULL;
2011
2012 /* Okay; we can pass our circuit list to entrynodes.c.*/
2013 smartlist_t *result = smartlist_new();
2014 int circuits_upgraded = entry_guards_upgrade_waiting_circuits(
2017 result);
2018 if (circuits_upgraded && smartlist_len(result)) {
2019 return result;
2020 } else {
2021 smartlist_free(result);
2022 return NULL;
2023 }
2024}
2025
2026/** Return the number of hops in circuit's path. If circ has no entries,
2027 * or is NULL, returns 0. */
2028int
2030{
2031 int n = 0;
2032 if (circ && circ->cpath) {
2033 crypt_path_t *cpath, *cpath_next = NULL;
2034 for (cpath = circ->cpath; cpath_next != circ->cpath; cpath = cpath_next) {
2035 cpath_next = cpath->next;
2036 ++n;
2037 }
2038 }
2039 return n;
2040}
2041
2042/** Return the number of opened hops in circuit's path.
2043 * If circ has no entries, or is NULL, returns 0. */
2044int
2046{
2047 int n = 0;
2048 if (circ && circ->cpath) {
2049 crypt_path_t *cpath, *cpath_next = NULL;
2050 for (cpath = circ->cpath;
2051 cpath->state == CPATH_STATE_OPEN
2052 && cpath_next != circ->cpath;
2053 cpath = cpath_next) {
2054 cpath_next = cpath->next;
2055 ++n;
2056 }
2057 }
2058 return n;
2059}
2060
2061/** Return the <b>hopnum</b>th hop in <b>circ</b>->cpath, or NULL if there
2062 * aren't that many hops in the list. <b>hopnum</b> starts at 1.
2063 * Returns NULL if <b>hopnum</b> is 0 or negative. */
2066{
2067 if (circ && circ->cpath && hopnum > 0) {
2068 crypt_path_t *cpath, *cpath_next = NULL;
2069 for (cpath = circ->cpath; cpath_next != circ->cpath; cpath = cpath_next) {
2070 cpath_next = cpath->next;
2071 if (--hopnum <= 0)
2072 return cpath;
2073 }
2074 }
2075 return NULL;
2076}
2077
2078/** Go through the circuitlist; mark-for-close each circuit that starts
2079 * at us but has not yet been used. */
2080void
2082{
2084 if (CIRCUIT_IS_ORIGIN(circ) &&
2085 !circ->marked_for_close &&
2086 !circ->timestamp_dirty)
2087 circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
2088 }
2089 SMARTLIST_FOREACH_END(circ);
2090}
2091
2092/** Go through the circuitlist; for each circuit that starts at us
2093 * and is dirty, frob its timestamp_dirty so we won't use it for any
2094 * new streams.
2095 *
2096 * This is useful for letting the user change pseudonyms, so new
2097 * streams will not be linkable to old streams.
2098 */
2099void
2101{
2103 if (CIRCUIT_IS_ORIGIN(circ) &&
2104 !circ->marked_for_close &&
2105 circ->timestamp_dirty) {
2107 }
2108 }
2109 SMARTLIST_FOREACH_END(circ);
2110}
2111
2112/**
2113 * Report any queued cells on or_circuits as written in our bandwidth
2114 * totals, for the specified channel direction.
2115 *
2116 * When we close a circuit or clear its cell queues, we've read
2117 * data and recorded those bytes in our read statistics, but we're
2118 * not going to write it. This discrepancy can be used by an adversary
2119 * to infer information from our public relay statistics and perform
2120 * attacks such as guard discovery.
2121 *
2122 * This function is in the critical path of circuit_mark_for_close().
2123 * It must be (and is) O(1)!
2124 *
2125 * See https://bugs.torproject.org/tpo/core/tor/23512
2126 */
2127void
2130{
2131 uint64_t cells;
2132 uint64_t cell_size;
2133 uint64_t written_sync;
2134 const channel_t *chan = NULL;
2135 const or_circuit_t *or_circ;
2136
2137 if (!CIRCUIT_IS_ORCIRC(c))
2138 return;
2139
2140 or_circ = CONST_TO_OR_CIRCUIT(c);
2141
2142 if (dir == CIRCUIT_N_CHAN) {
2143 chan = c->n_chan;
2144 cells = c->n_chan_cells.n;
2145 } else {
2146 chan = or_circ->p_chan;
2147 cells = or_circ->p_chan_cells.n;
2148 }
2149
2150 /* If we still know the chan, determine real cell size. Otherwise,
2151 * assume it's a wide circid channel */
2152 if (chan)
2153 cell_size = get_cell_network_size(chan->wide_circ_ids);
2154 else
2155 cell_size = CELL_MAX_NETWORK_SIZE;
2156
2157 /* If we know the channel, find out if it's IPv6. */
2158 tor_addr_t remote_addr;
2159 bool is_ipv6 = chan &&
2160 channel_get_addr_if_possible(chan, &remote_addr) &&
2161 tor_addr_family(&remote_addr) == AF_INET6;
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 bwhist_note_bytes_written(written_sync, time(NULL), is_ipv6);
2171}
2172
2173/** Mark <b>circ</b> to be closed next time we call
2174 * circuit_close_all_marked(). Do any cleanup needed:
2175 * - If state is onionskin_pending, remove circ from the onion_pending
2176 * list.
2177 * - If circ isn't open yet: call circuit_build_failed() if we're
2178 * the origin.
2179 * - If purpose is C_INTRODUCE_ACK_WAIT, report the intro point
2180 * failure we just had to the hidden service client module.
2181 * - If purpose is C_INTRODUCING and <b>reason</b> isn't TIMEOUT,
2182 * report to the hidden service client module that the intro point
2183 * we just tried may be unreachable.
2184 * - Send appropriate destroys and edge_destroys for conns and
2185 * streams attached to circ.
2186 * - If circ->rend_splice is set (we are the midpoint of a joined
2187 * rendezvous stream), then mark the other circuit to close as well.
2188 */
2189MOCK_IMPL(void,
2190circuit_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. */
2259
2260 /* Specific actions if this is a conflux related circuit. */
2261 if (CIRCUIT_IS_CONFLUX(circ)) {
2263 }
2264
2265 /* Update stats. */
2266 if (circ->ccontrol) {
2267 if (circ->ccontrol->in_slow_start) {
2268 /* If we are in slow start, only count the ss cwnd if we've sent
2269 * enough data to get RTT measurements such that we have a min
2270 * and a max RTT, and they are not the same. This prevents us from
2271 * averaging and reporting unused and low-use circuits here */
2272 if (circ->ccontrol->max_rtt_usec != circ->ccontrol->min_rtt_usec) {
2274 stats_update_running_avg(cc_stats_circ_close_ss_cwnd_ma,
2275 circ->ccontrol->cwnd);
2276 }
2277 } else {
2279 stats_update_running_avg(cc_stats_circ_close_cwnd_ma,
2280 circ->ccontrol->cwnd);
2281 }
2282 cc_stats_circs_closed++;
2283 }
2284
2285 if (circuits_pending_close == NULL)
2287
2290
2291 log_info(LD_GENERAL, "Circuit %u (id: %" PRIu32 ") marked for close at "
2292 "%s:%d (orig reason: %d, new reason: %d)",
2293 circ->n_circ_id,
2294 CIRCUIT_IS_ORIGIN(circ) ?
2295 TO_ORIGIN_CIRCUIT(circ)->global_identifier : 0,
2296 file, line, orig_reason, reason);
2297 tor_trace(TR_SUBSYS(circuit), TR_EV(mark_for_close), circ);
2298}
2299
2300/** Called immediately before freeing a marked circuit <b>circ</b> from
2301 * circuit_free_all() while shutting down Tor; this is a safe-at-shutdown
2302 * version of circuit_about_to_free(). It's important that it at least
2303 * do circuitmux_detach_circuit() when appropriate.
2304 */
2305static void
2307{
2308 /* Cleanup conflux specifics. */
2310
2311 if (circ->n_chan) {
2312 circuit_clear_cell_queue(circ, circ->n_chan);
2314 circuit_set_n_circid_chan(circ, 0, NULL);
2315 }
2316
2317 if (! CIRCUIT_IS_ORIGIN(circ)) {
2318 or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
2319
2320 if (or_circ->p_chan) {
2321 circuit_clear_cell_queue(circ, or_circ->p_chan);
2322 circuitmux_detach_circuit(or_circ->p_chan->cmux, circ);
2323 circuit_set_p_circid_chan(or_circ, 0, NULL);
2324 }
2325 }
2326}
2327
2328/** Called immediately before freeing a marked circuit <b>circ</b>.
2329 * Disconnects the circuit from other data structures, launches events
2330 * as appropriate, and performs other housekeeping.
2331 */
2332static void
2334{
2335
2336 int reason = circ->marked_for_close_reason;
2337 int orig_reason = circ->marked_for_close_orig_reason;
2338
2339 /* Cleanup conflux specifics. */
2341
2344 }
2345 /* If the circuit ever became OPEN, we sent it to the reputation history
2346 * module then. If it isn't OPEN, we send it there now to remember which
2347 * links worked and which didn't.
2348 */
2349 if (circ->state != CIRCUIT_STATE_OPEN &&
2351 if (CIRCUIT_IS_ORIGIN(circ)) {
2352 origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
2353 circuit_build_failed(ocirc); /* take actions if necessary */
2354 }
2355 }
2356 if (circ->state == CIRCUIT_STATE_CHAN_WAIT) {
2359 }
2362 }
2363 if (CIRCUIT_IS_ORIGIN(circ)) {
2365 (circ->state == CIRCUIT_STATE_OPEN ||
2367 CIRC_EVENT_CLOSED:CIRC_EVENT_FAILED,
2368 orig_reason);
2369 }
2370
2371 if (circ->n_chan) {
2372 circuit_clear_cell_queue(circ, circ->n_chan);
2373 /* Only send destroy if the channel isn't closing anyway */
2374 if (!CHANNEL_CONDEMNED(circ->n_chan)) {
2375 channel_send_destroy(circ->n_circ_id, circ->n_chan, reason);
2376 }
2378 circuit_set_n_circid_chan(circ, 0, NULL);
2379 }
2380
2381 if (! CIRCUIT_IS_ORIGIN(circ)) {
2382 or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
2383 edge_connection_t *conn;
2384
2385 for (conn=or_circ->n_streams; conn; conn=conn->next_stream)
2386 connection_edge_destroy(or_circ->p_circ_id, conn);
2387 or_circ->n_streams = NULL;
2388
2389 while (or_circ->resolving_streams) {
2390 conn = or_circ->resolving_streams;
2391 or_circ->resolving_streams = conn->next_stream;
2392 if (!conn->base_.marked_for_close) {
2393 /* The client will see a DESTROY, and infer that the connections
2394 * are closing because the circuit is getting torn down. No need
2395 * to send an end cell. */
2396 conn->edge_has_sent_end = 1;
2397 conn->end_reason = END_STREAM_REASON_DESTROY;
2399 connection_mark_for_close(TO_CONN(conn));
2400 }
2401 conn->on_circuit = NULL;
2402 }
2403
2404 if (or_circ->p_chan) {
2405 circuit_clear_cell_queue(circ, or_circ->p_chan);
2406 /* Only send destroy if the channel isn't closing anyway */
2407 if (!CHANNEL_CONDEMNED(or_circ->p_chan)) {
2408 channel_send_destroy(or_circ->p_circ_id, or_circ->p_chan, reason);
2409 }
2410 circuitmux_detach_circuit(or_circ->p_chan->cmux, circ);
2411 circuit_set_p_circid_chan(or_circ, 0, NULL);
2412 }
2413
2414 if (or_circ->n_cells_discarded_at_end) {
2415 time_t age = approx_time() - circ->timestamp_created.tv_sec;
2417 age, or_circ->n_cells_discarded_at_end);
2418 }
2419 } else {
2420 origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
2421 edge_connection_t *conn;
2422 for (conn=ocirc->p_streams; conn; conn=conn->next_stream)
2424 ocirc->p_streams = NULL;
2425 }
2426}
2427
2428/** Given a marked circuit <b>circ</b>, aggressively free its cell queues to
2429 * recover memory. */
2430static void
2432{
2433 if (!circ->marked_for_close) {
2434 log_warn(LD_BUG, "Called on non-marked circuit");
2435 return;
2436 }
2438 if (! CIRCUIT_IS_ORIGIN(circ)) {
2439 or_circuit_t *orcirc = TO_OR_CIRCUIT(circ);
2441 }
2442}
2443
2444static size_t
2445single_conn_free_bytes(connection_t *conn)
2446{
2447 size_t result = 0;
2448 if (conn->inbuf) {
2449 result += buf_allocation(conn->inbuf);
2450 buf_clear(conn->inbuf);
2451 }
2452 if (conn->outbuf) {
2453 result += buf_allocation(conn->outbuf);
2454 buf_clear(conn->outbuf);
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
2467/** Aggressively free buffer contents on all the buffers of all streams in the
2468 * list starting at <b>stream</b>. Return the number of bytes recovered. */
2469static 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
2483/** Aggressively free buffer contents on all the buffers of all streams on
2484 * circuit <b>c</b>. Return the number of bytes recovered. */
2485static size_t
2487{
2488 if (CIRCUIT_IS_ORIGIN(c)) {
2490 } else {
2492 }
2493}
2494
2495/** Return the number of cells used by the circuit <b>c</b>'s cell queues. */
2496STATIC 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
2507/** Return the number of bytes allocated for <b>c</b>'s half-open streams. */
2508static 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
2521/**
2522 * Return the age of the oldest cell queued on <b>c</b>, in timestamp units.
2523 * Return 0 if there are no cells queued on c. Requires that <b>now</b> be
2524 * the current coarse timestamp.
2525 *
2526 * This function will return incorrect results if the oldest cell queued on
2527 * the circuit is older than about 2**32 msec (about 49 days) old.
2528 */
2529STATIC 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
2549/** Return the age of the oldest buffer chunk on <b>conn</b>, where age is
2550 * taken in timestamp units before the time <b>now</b>. If the connection has
2551 * no data, treat it as having age zero.
2552 **/
2553static uint32_t
2554conn_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
2570/** Return the age in timestamp units of the oldest buffer chunk on any stream
2571 * in the linked list <b>stream</b>, where age is taken in timestamp units
2572 * before the timestamp <b>now</b>. */
2573static 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
2591/** Return the age in timestamp units of the oldest buffer chunk on any stream
2592 * attached to the circuit <b>c</b>, where age is taken before the timestamp
2593 * <b>now</b>. */
2594STATIC 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
2606/** Return the age of the oldest cell or stream buffer chunk on the circuit
2607 * <b>c</b>, where age is taken in timestamp units before the timestamp
2608 * <b>now</b> */
2609STATIC 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
2620/** Helper to sort a list of circuit_t by age of oldest item, in descending
2621 * order. */
2622static int
2623circuits_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
2638static uint32_t now_ts_for_buf_cmp;
2639
2640/** Helper to sort a list of circuit_t by age of oldest item, in descending
2641 * order. */
2642static int
2643conns_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
2660/** We're out of memory for cells, having allocated <b>current_allocation</b>
2661 * bytes' worth. Kill the 'worst' circuits until we're under
2662 * FRACTION_OF_DATA_TO_RETAIN_ON_OOM of our maximum usage.
2663 *
2664 * Return the number of bytes removed. */
2665size_t
2666circuits_handle_oom(size_t current_allocation)
2667{
2668 smartlist_t *circlist;
2670 int conn_idx;
2671 size_t mem_to_recover;
2672 size_t mem_recovered=0;
2673 int n_circuits_killed=0;
2674 int n_dirconns_killed=0;
2675 int n_edgeconns_killed = 0;
2676 uint32_t now_ts;
2677 log_notice(LD_GENERAL, "We're low on memory (cell queues total alloc:"
2678 " %"TOR_PRIuSZ" buffer total alloc: %" TOR_PRIuSZ ","
2679 " tor compress total alloc: %" TOR_PRIuSZ
2680 " (zlib: %" TOR_PRIuSZ ", zstd: %" TOR_PRIuSZ ","
2681 " lzma: %" TOR_PRIuSZ "),"
2682 " rendezvous cache total alloc: %" TOR_PRIuSZ "). Killing"
2683 " circuits withover-long queues. (This behavior is controlled by"
2684 " MaxMemInQueues.)",
2685 cell_queues_get_total_allocation(),
2686 buf_get_total_allocation(),
2691 hs_cache_get_total_allocation());
2692 {
2693 size_t mem_target = (size_t)(get_options()->MaxMemInQueues *
2694 FRACTION_OF_DATA_TO_RETAIN_ON_OOM);
2695 if (current_allocation <= mem_target)
2696 return 0;
2697 mem_to_recover = current_allocation - mem_target;
2698 }
2699
2700 now_ts = monotime_coarse_get_stamp();
2701
2702 circlist = circuit_get_global_list();
2703 SMARTLIST_FOREACH_BEGIN(circlist, circuit_t *, circ) {
2704 circ->age_tmp = circuit_max_queued_item_age(circ, now_ts);
2705 } SMARTLIST_FOREACH_END(circ);
2706
2707 /* This is O(n log n); there are faster algorithms we could use instead.
2708 * Let's hope this doesn't happen enough to be in the critical path. */
2710
2711 /* Fix up the indices before we run into trouble */
2712 SMARTLIST_FOREACH_BEGIN(circlist, circuit_t *, circ) {
2713 circ->global_circuitlist_idx = circ_sl_idx;
2714 } SMARTLIST_FOREACH_END(circ);
2715
2716 /* Now sort the connection array ... */
2717 now_ts_for_buf_cmp = now_ts;
2719 now_ts_for_buf_cmp = 0;
2720
2721 /* Fix up the connection array to its new order. */
2723 conn->conn_array_index = conn_sl_idx;
2724 } SMARTLIST_FOREACH_END(conn);
2725
2726 /* Okay, now the worst circuits and connections are at the front of their
2727 * respective lists. Let's mark them, and reclaim their storage
2728 * aggressively. */
2729 conn_idx = 0;
2730 SMARTLIST_FOREACH_BEGIN(circlist, circuit_t *, circ) {
2731 size_t n;
2732 size_t freed;
2733
2734 /* Free storage in any non-linked directory connections that have buffered
2735 * data older than this circuit. */
2736 while (conn_idx < smartlist_len(connection_array)) {
2737 connection_t *conn = smartlist_get(connection_array, conn_idx);
2738 uint32_t conn_age = conn_get_buffer_age(conn, now_ts);
2739 if (conn_age < circ->age_tmp) {
2740 break;
2741 }
2742 /* Also consider edge connections so we don't accumulate bytes on the
2743 * outbuf due to a malicious destination holding off the read on us. */
2744 if ((conn->type == CONN_TYPE_DIR && conn->linked_conn == NULL) ||
2745 CONN_IS_EDGE(conn)) {
2746 if (!conn->marked_for_close)
2747 connection_mark_for_close(conn);
2748 mem_recovered += single_conn_free_bytes(conn);
2749
2750 if (conn->type == CONN_TYPE_DIR) {
2751 ++n_dirconns_killed;
2752 } else {
2753 ++n_edgeconns_killed;
2754 }
2755
2756 if (mem_recovered >= mem_to_recover)
2757 goto done_recovering_mem;
2758 }
2759 ++conn_idx;
2760 }
2761
2762 /* Now, kill the circuit. */
2763 n = n_cells_in_circ_queues(circ);
2764 const size_t half_stream_alloc = circuit_alloc_in_half_streams(circ);
2765 if (! circ->marked_for_close) {
2766 circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT);
2767 }
2770
2771 ++n_circuits_killed;
2772
2773 mem_recovered += n * packed_cell_mem_cost();
2774 mem_recovered += half_stream_alloc;
2775 mem_recovered += freed;
2776 mem_recovered += conflux_get_circ_bytes_allocation(circ);
2777
2778 if (mem_recovered >= mem_to_recover)
2779 goto done_recovering_mem;
2780 } SMARTLIST_FOREACH_END(circ);
2781
2782 done_recovering_mem:
2783 log_notice(LD_GENERAL, "Removed %"TOR_PRIuSZ" bytes by killing %d circuits; "
2784 "%d circuits remain alive. Also killed %d non-linked directory "
2785 "connections. Killed %d edge connections",
2786 mem_recovered,
2787 n_circuits_killed,
2788 smartlist_len(circlist) - n_circuits_killed,
2789 n_dirconns_killed,
2790 n_edgeconns_killed);
2791
2792 return mem_recovered;
2793}
2794
2795/** Verify that circuit <b>c</b> has all of its invariants
2796 * correct. Trigger an assert if anything is invalid.
2797 */
2798MOCK_IMPL(void,
2800{
2801 edge_connection_t *conn;
2802 const or_circuit_t *or_circ = NULL;
2803 const origin_circuit_t *origin_circ = NULL;
2804
2805 tor_assert(c);
2807 tor_assert(c->purpose >= CIRCUIT_PURPOSE_MIN_ &&
2808 c->purpose <= CIRCUIT_PURPOSE_MAX_);
2809
2810 if (CIRCUIT_IS_ORIGIN(c))
2811 origin_circ = CONST_TO_ORIGIN_CIRCUIT(c);
2812 else
2813 or_circ = CONST_TO_OR_CIRCUIT(c);
2814
2815 if (c->n_chan) {
2816 tor_assert(!c->n_hop);
2817
2818 if (c->n_circ_id) {
2819 /* We use the _impl variant here to make sure we don't fail on marked
2820 * circuits, which would not be returned by the regular function. */
2822 c->n_chan, NULL);
2823 tor_assert(c == c2);
2824 }
2825 }
2826 if (or_circ && or_circ->p_chan) {
2827 if (or_circ->p_circ_id) {
2828 /* ibid */
2829 circuit_t *c2 =
2831 or_circ->p_chan, NULL);
2832 tor_assert(c == c2);
2833 }
2834 }
2835 if (or_circ)
2836 for (conn = or_circ->n_streams; conn; conn = conn->next_stream)
2837 tor_assert(conn->base_.type == CONN_TYPE_EXIT);
2838
2839 tor_assert(c->deliver_window >= 0);
2840 tor_assert(c->package_window >= 0);
2841 if (c->state == CIRCUIT_STATE_OPEN ||
2844 if (or_circ) {
2845 relay_crypto_assert_ok(&or_circ->crypto);
2846 }
2847 }
2851 } else {
2854 }
2855 if (origin_circ && origin_circ->cpath) {
2856 cpath_assert_ok(origin_circ->cpath);
2857 }
2859 tor_assert(or_circ);
2860 if (!c->marked_for_close) {
2861 tor_assert(or_circ->rend_splice);
2862 tor_assert(or_circ->rend_splice->rend_splice == or_circ);
2863 }
2864 tor_assert(or_circ->rend_splice != or_circ);
2865 } else {
2866 tor_assert(!or_circ || !or_circ->rend_splice);
2867 }
2868}
2869
2870/** Return true iff the circuit queue for the given direction is full that is
2871 * above the high watermark. */
2872bool
2874{
2875 int queue_size;
2876
2877 tor_assert(circ);
2878
2879 /* Gather objects we need based on cell direction. */
2880 if (direction == CELL_DIRECTION_OUT) {
2881 /* Outbound. */
2882 queue_size = circ->n_chan_cells.n;
2883 } else {
2884 /* Inbound. */
2885 queue_size = CONST_TO_OR_CIRCUIT(circ)->p_chan_cells.n;
2886 }
2887
2888 /* Then check if our cell queue has reached its high watermark as in its
2889 * upper limit. This is so we avoid too much memory pressure by queuing a
2890 * large amount of cells. */
2891 return queue_size >= cell_queue_highwatermark();
2892}
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:3295
int channel_send_destroy(circid_t circ_id, channel_t *chan, int reason)
Definition: channel.c:2038
int channel_get_addr_if_possible(const channel_t *chan, tor_addr_t *addr_out)
Definition: channel.c:2860
const char * channel_describe_peer(channel_t *chan)
Definition: channel.c:2840
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:357
int route_len_for_purpose(uint8_t purpose, extend_info_t *exit_ei)
Header file for circuitbuild.c.
static circuit_t * circuit_get_by_circid_channel_impl(circid_t circ_id, channel_t *chan, int *found_entry_out)
Definition: circuitlist.c:1471
STATIC uint32_t circuit_max_queued_item_age(const circuit_t *c, uint32_t now)
Definition: circuitlist.c:2610
static int chan_circid_entries_eq_(chan_circid_circuit_map_t *a, chan_circid_circuit_map_t *b)
Definition: circuitlist.c:207
static uint32_t circuit_get_streams_max_data_age(const edge_connection_t *stream, uint32_t now)
Definition: circuitlist.c:2574
STATIC void circuit_free_(circuit_t *circ)
Definition: circuitlist.c:1153
void circuit_close_all_marked(void)
Definition: circuitlist.c:676
const char * circuit_purpose_to_controller_hs_state_string(uint8_t purpose)
Definition: circuitlist.c:862
void circuit_mark_for_close_(circuit_t *circ, int reason, int line, const char *file)
Definition: circuitlist.c:2191
static smartlist_t * global_circuitlist
Definition: circuitlist.c:127
int circuit_any_opened_circuits_cached(void)
Definition: circuitlist.c:769
void channel_note_destroy_pending(channel_t *chan, circid_t id)
Definition: circuitlist.c:423
static int any_opened_circs_cached_val
Definition: circuitlist.c:153
circuit_t * circuit_get_by_circid_channel_even_if_marked(circid_t circ_id, channel_t *chan)
Definition: circuitlist.c:1554
void circuit_set_p_circid_chan(or_circuit_t *or_circ, circid_t id, channel_t *chan)
Definition: circuitlist.c:465
origin_circuit_t * circuit_get_next_by_purpose(origin_circuit_t *start, uint8_t purpose)
Definition: circuitlist.c:1798
int circuit_id_in_use_on_channel(circid_t circ_id, channel_t *chan)
Definition: circuitlist.c:1568
STATIC size_t n_cells_in_circ_queues(const circuit_t *c)
Definition: circuitlist.c:2497
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:1385
or_circuit_t * or_circuit_new(circid_t p_circ_id, channel_t *p_chan)
Definition: circuitlist.c:1118
void circuit_synchronize_written_or_bandwidth(const circuit_t *c, circuit_channel_direction_t dir)
Definition: circuitlist.c:2128
void circuit_set_n_circid_chan(circuit_t *circ, circid_t id, channel_t *chan)
Definition: circuitlist.c:488
double cc_stats_circ_close_ss_cwnd_ma
Definition: circuitlist.c:158
static void init_circuit_base(circuit_t *circ)
Definition: circuitlist.c:1016
static uint32_t conn_get_buffer_age(const connection_t *conn, uint32_t now_ts)
Definition: circuitlist.c:2554
void circuit_mark_all_dirty_circs_as_unusable(void)
Definition: circuitlist.c:2100
static int circuits_compare_by_oldest_queued_item_(const void **a_, const void **b_)
Definition: circuitlist.c:2623
void circuit_clear_cpath(origin_circuit_t *circ)
Definition: circuitlist.c:1307
void circuit_set_state(circuit_t *circ, uint8_t state)
Definition: circuitlist.c:557
void circuit_free_all(void)
Definition: circuitlist.c:1331
circuit_t * circuit_get_by_edge_conn(edge_connection_t *conn)
Definition: circuitlist.c:1600
smartlist_t * circuit_find_circuits_to_upgrade_from_guard_wait(void)
Definition: circuitlist.c:2001
origin_circuit_t * circuit_get_next_intro_circ(const origin_circuit_t *start, bool want_client_circ)
Definition: circuitlist.c:1715
origin_circuit_t * circuit_get_by_global_id(uint32_t id)
Definition: circuitlist.c:1447
origin_circuit_t * origin_circuit_new(void)
Definition: circuitlist.c:1045
static unsigned int chan_circid_entry_hash_(chan_circid_circuit_map_t *a)
Definition: circuitlist.c:216
void channel_mark_circid_unusable(channel_t *chan, circid_t id)
Definition: circuitlist.c:367
void circuit_dump_by_conn(connection_t *conn, int severity)
Definition: circuitlist.c:1406
int circuit_any_opened_circuits(void)
Definition: circuitlist.c:732
origin_circuit_t * TO_ORIGIN_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:180
STATIC uint32_t circuit_max_queued_data_age(const circuit_t *c, uint32_t now)
Definition: circuitlist.c:2595
int circuit_get_cpath_len(origin_circuit_t *circ)
Definition: circuitlist.c:2029
void channel_mark_circid_usable(channel_t *chan, circid_t id)
Definition: circuitlist.c:400
static smartlist_t * circuits_pending_close
Definition: circuitlist.c:142
int circuit_get_cpath_opened_len(const origin_circuit_t *circ)
Definition: circuitlist.c:2045
const char * circuit_purpose_to_controller_string(uint8_t purpose)
Definition: circuitlist.c:796
void assert_circuit_ok(const circuit_t *c)
Definition: circuitlist.c:2799
static void circuit_remove_from_origin_circuit_list(origin_circuit_t *origin_circ)
Definition: circuitlist.c:643
static smartlist_t * circuits_pending_other_guards
Definition: circuitlist.c:138
const char * circuit_state_to_string(int state)
Definition: circuitlist.c:776
static size_t marked_circuit_free_stream_bytes(circuit_t *c)
Definition: circuitlist.c:2486
int circuit_count_pending_on_channel(channel_t *chan)
Definition: circuitlist.c:623
static HT_HEAD(HT_PROTOTYPE(chan_circid_map, HT_PROTOTYPE(chan_circid_circuit_map_t)
Definition: circuitlist.c:230
STATIC uint32_t circuit_max_queued_cell_age(const circuit_t *c, uint32_t now)
Definition: circuitlist.c:2530
static int conns_compare_by_buffer_age_(const void **a_, const void **b_)
Definition: circuitlist.c:2643
size_t circuits_handle_oom(size_t current_allocation)
Definition: circuitlist.c:2666
void circuit_get_all_pending_on_channel(smartlist_t *out, channel_t *chan)
Definition: circuitlist.c:592
static void circuit_about_to_free(circuit_t *circ)
Definition: circuitlist.c:2333
int circuit_event_status(origin_circuit_t *circ, circuit_status_event_t tp, int reason_code)
Definition: circuitlist.c:513
or_circuit_t * TO_OR_CIRCUIT(circuit_t *x)
Definition: circuitlist.c:168
static void circuit_about_to_free_atexit(circuit_t *circ)
Definition: circuitlist.c:2306
static size_t marked_circuit_streams_free_bytes(edge_connection_t *stream)
Definition: circuitlist.c:2470
time_t circuit_id_when_marked_unusable_on_channel(circid_t circ_id, channel_t *chan)
Definition: circuitlist.c:1581
void circuit_cache_opened_circuit_state(int circuits_are_opened)
Definition: circuitlist.c:758
#define DFLT_IDLE_TIMEOUT_WHILE_LEARNING
Definition: circuitlist.c:1037
origin_circuit_t * circuit_get_next_service_rp_circ(origin_circuit_t *start)
Definition: circuitlist.c:1767
circuit_t * circuit_get_by_circid_channel(circid_t circ_id, channel_t *chan)
Definition: circuitlist.c:1539
static void circuit_add_to_origin_circuit_list(origin_circuit_t *origin_circ)
Definition: circuitlist.c:664
double cc_stats_circ_close_cwnd_ma
Definition: circuitlist.c:156
static smartlist_t * circuits_pending_chans
Definition: circuitlist.c:134
crypt_path_t * circuit_get_cpath_hop(origin_circuit_t *circ, int hopnum)
Definition: circuitlist.c:2065
origin_circuit_t * circuit_find_to_cannibalize(uint8_t purpose_to_produce, extend_info_t *info, int flags)
Definition: circuitlist.c:1887
const char * circuit_purpose_to_string(uint8_t purpose)
Definition: circuitlist.c:924
static uint8_t get_circuit_purpose_needed_to_cannibalize(uint8_t purpose)
Definition: circuitlist.c:1853
void channel_note_destroy_not_pending(channel_t *chan, circid_t id)
Definition: circuitlist.c:443
static void circuit_state_publish(const circuit_t *circ)
Definition: circuitlist.c:537
void circuit_clear_testing_cell_stats(circuit_t *circ)
Definition: circuitlist.c:1140
static size_t circuit_alloc_in_half_streams(const circuit_t *c)
Definition: circuitlist.c:2509
smartlist_t * circuit_get_global_origin_circuit_list(void)
Definition: circuitlist.c:717
bool circuit_is_queue_full(const circuit_t *circ, cell_direction_t direction)
Definition: circuitlist.c:2873
smartlist_t * circuit_get_global_list(void)
Definition: circuitlist.c:708
void circuit_unlink_all_from_channel(channel_t *chan, int reason)
Definition: circuitlist.c:1617
static void marked_circuit_free_cells(circuit_t *circ)
Definition: circuitlist.c:2431
static int circuit_can_be_cannibalized_for_v3_rp(const origin_circuit_t *circ)
Definition: circuitlist.c:1828
static smartlist_t * global_origin_circuit_list
Definition: circuitlist.c:131
void circuit_mark_all_unused_circs(void)
Definition: circuitlist.c:2081
int32_t circuit_initial_package_window(void)
Definition: circuitlist.c:1002
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:161
#define CIRCUIT_PURPOSE_IS_ORIGIN(p)
Definition: circuitlist.h:147
#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:154
#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_CONFLUX_UNLINKED
Definition: circuitlist.h:137
#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.
circuit_build_times_t * get_circuit_build_times_mutable(void)
Definition: circuitstats.c:85
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
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:1756
int circuit_should_use_vanguards(uint8_t purpose)
Definition: circuituse.c:2013
void mark_circuit_unusable_for_new_conns(origin_circuit_t *circ)
Definition: circuituse.c:3148
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:864
size_t tor_compress_state_size(const tor_compress_state_t *state)
Definition: compress.c:647
size_t tor_compress_get_total_allocation(void)
Definition: compress.c:466
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:944
Header file for config.c.
uint64_t conflux_get_circ_bytes_allocation(const circuit_t *circ)
Definition: conflux.c:167
Public APIs for conflux multipath support.
void conflux_circuit_has_closed(circuit_t *circ)
void conflux_circuit_about_to_free(circuit_t *circ)
Header file for conflux_pool.c.
Header file for conflux_util.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:972
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:2571
int entry_guards_upgrade_waiting_circuits(guard_selection_t *gs, const smartlist_t *all_circuits_in, smartlist_t *newly_complete_out)
Definition: entrynodes.c:2696
int entry_guard_could_succeed(const circuit_guard_state_t *guard_state)
Definition: entrynodes.c:3638
guard_selection_t * get_guard_selection_info(void)
Definition: entrynodes.c:312
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:1605
void hs_circ_cleanup_on_free(circuit_t *circ)
Definition: hs_circuit.c:1631
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:1645
Header file for mainloop.c.
void * tor_reallocarray_(void *ptr, size_t sz1, size_t sz2)
Definition: malloc.c:146
void tor_free_(void *mem)
Definition: malloc.c:227
#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.
const node_t * node_get_by_id(const char *identity_digest)
Definition: nodelist.c:226
bool node_supports_v3_rendezvous_point(const node_t *node)
Definition: nodelist.c:1271
int nodes_in_same_family(const node_t *node1, const node_t *node2)
Definition: nodelist.c:2204
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:902
#define MAX_RELAY_EARLY_CELLS_PER_CIRCUIT
Definition: or.h:837
#define CELL_MAX_NETWORK_SIZE
Definition: or.h:468
uint32_t circid_t
Definition: or.h:497
#define TO_CIRCUIT(x)
Definition: or.h:848
#define CIRCWINDOW_START
Definition: or.h:394
#define END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED
Definition: or.h:292
#define TO_CONN(c)
Definition: or.h:612
#define END_CIRC_REASON_FLAG_REMOTE
Definition: or.h:341
cell_direction_t
Definition: or.h:375
@ CELL_DIRECTION_OUT
Definition: or.h:377
@ CELL_DIRECTION_IN
Definition: or.h:376
#define DOWNCAST(to, ptr)
Definition: or.h:109
#define END_CIRC_AT_ORIGIN
Definition: or.h:318
circuit_channel_direction_t
Definition: or.h:387
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:3023
void circuit_reset_sendme_randomness(circuit_t *circ)
Definition: relay.c:2237
void cell_queue_clear(cell_queue_t *queue)
Definition: relay.c:2780
void circuit_clear_cell_queue(circuit_t *circ, channel_t *chan)
Definition: relay.c:3529
void cell_queue_init(cell_queue_t *queue)
Definition: relay.c:2772
size_t packed_cell_mem_cost(void)
Definition: relay.c:2873
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
int smartlist_contains(const smartlist_t *sl, const void *element)
smartlist_t * smartlist_new(void)
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:50
channel_t * p_chan
Definition: or_circuit_st.h:37
unsigned int remaining_relay_early_cells
Definition: or_circuit_st.h:69
struct workqueue_entry_t * workqueue_entry
Definition: or_circuit_st.h:30
uint32_t n_cells_discarded_at_end
Definition: or_circuit_st.h:65
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:58
edge_connection_t * n_streams
Definition: or_circuit_st.h:43
relay_crypto_t crypto
Definition: or_circuit_st.h:54
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:820
#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