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