tor
master
|
Launch the right sort of circuits and attach the right streams to them. More...
#include "or.h"
#include "addressmap.h"
#include "bridges.h"
#include "channel.h"
#include "circpathbias.h"
#include "circuitbuild.h"
#include "circuitlist.h"
#include "circuitstats.h"
#include "circuituse.h"
#include "config.h"
#include "connection.h"
#include "connection_edge.h"
#include "control.h"
#include "entrynodes.h"
#include "hs_common.h"
#include "hs_client.h"
#include "hs_circuit.h"
#include "hs_ident.h"
#include "hs_stats.h"
#include "nodelist.h"
#include "networkstatus.h"
#include "policies.h"
#include "rendclient.h"
#include "rendcommon.h"
#include "rendservice.h"
#include "rephist.h"
#include "router.h"
#include "routerlist.h"
Macros | |
#define | SET_CUTOFF(target, msec) |
#define | MAX_ANCIENT_ONEHOP_CIRCUITS_TO_LOG 10 |
#define | MAX_UNUSED_OPEN_CIRCUITS 14 |
#define | SUFFICIENT_UPTIME_INTERNAL_HS_SERVERS 3 |
#define | SUFFICIENT_INTERNAL_HS_CLIENTS 3 |
#define | SUFFICIENT_UPTIME_INTERNAL_HS_CLIENTS 2 |
#define | DFLT_CBT_UNUSED_OPEN_CIRCS (10) |
#define | MIN_CBT_UNUSED_OPEN_CIRCS 0 |
#define | MAX_CBT_UNUSED_OPEN_CIRCS MAX_UNUSED_OPEN_CIRCUITS |
#define | TESTING_CIRCUIT_INTERVAL 300 |
#define | IDLE_ONE_HOP_CIRC_TIMEOUT 60 |
#define | NUM_PARALLEL_TESTING_CIRCS 4 |
#define | MAX_CIRCUIT_FAILURES 5 |
Launch the right sort of circuits and attach the right streams to them.
As distinct from circuitlist.c, which manages lookups to find circuits, and circuitbuild.c, which handles the logistics of circuit construction, this module keeps track of which streams can be attached to which circuits (in circuit_get_best()), and attaches streams to circuits (with circuit_try_attaching_streams(), connection_ap_handshake_attach_circuit(), and connection_ap_handshake_attach_chosen_circuit() ).
This module also makes sure that we are building circuits for all of the predicted ports, using circuit_remove_handled_ports(), circuit_stream_is_being_handled(), and circuit_build_needed_cirs(). It handles launching circuits for specific targets using circuit_launch_by_extend_info().
This is also where we handle expiring circuits that have been around for too long without actually completing, along with the circuit_build_timeout logic in circuitstats.c.
#define IDLE_ONE_HOP_CIRC_TIMEOUT 60 |
How long do we wait before killing circuits with the properties described below?
Probably we could choose a number here as low as 5 to 10 seconds, since these circs are used for begindir, and a) generally you either ask another begindir question right after or you don't for a long time, b) clients at least through 0.2.1.x choose from the whole set of directory mirrors at each choice, and c) re-establishing a one-hop circuit via create-fast is a light operation assuming the TLS conn is still there.
I expect "b" to go away one day when we move to using directory guards, but I think "a" and "c" are good enough reasons that a low number is safe even then.
#define MAX_CIRCUIT_FAILURES 5 |
Don't retry launching a new circuit if we try this many times with no success.
#define MAX_UNUSED_OPEN_CIRCUITS 14 |
Don't keep more than this many unused open circuits around.
#define NUM_PARALLEL_TESTING_CIRCS 4 |
Number of testing circuits we want open before testing our bandwidth.
#define SET_CUTOFF | ( | target, | |
msec | |||
) |
#define TESTING_CIRCUIT_INTERVAL 300 |
Build a new test circuit every 5 minutes
void circuit_build_failed | ( | origin_circuit_t * | circ | ) |
Called whenever a circuit could not be successfully built.
void circuit_build_needed_circs | ( | time_t | now | ) |
This function is called once a second, if router_have_minimum_dir_info() is true. Its job is to make sure all services we offer have enough circuits available. Some services just want enough circuits for current tasks, whereas others want a minimum set of idle circuits hanging around.
void circuit_change_purpose | ( | circuit_t * | circ, |
uint8_t | new_purpose | ||
) |
Change circ's purpose to new_purpose.
void circuit_detach_stream | ( | circuit_t * | circ, |
edge_connection_t * | conn | ||
) |
If the stream conn is a member of any of the linked lists of circ, then remove it from the list.
int circuit_enough_testing_circs | ( | void | ) |
Return 1 if we've already exercised our bandwidth, or if we have fewer than NUM_PARALLEL_TESTING_CIRCS testing circuits established or on the way. Else return 0.
void circuit_expire_building | ( | void | ) |
Close all circuits that start at us, aren't open, and were born at least CircuitBuildTimeout seconds ago.
TODO: This function is now partially redundant to circuit_build_times_handle_completed_hop(), but that function only covers circuits up to and including 3 hops that are still actually completing hops. However, circuit_expire_building() also handles longer circuits, as well as circuits that are completely stalled. In the future (after prop247/other path selection revamping), we probably want to eliminate this rats nest in favor of a simpler approach.
Because circuit build timeout is calculated only based on 3 hop general purpose circuit construction, we need to scale the timeout to make it properly apply to longer circuits, and circuits of certain usage types. The following diagram illustrates how we derive the scaling below. In short, we calculate the number of times our telescoping-based circuit construction causes cells to traverse each link for the circuit purpose types in question, and then assume each link is equivalent.
OP –a–> A –b–> B –c–> C OP –a–> A –b–> B –c–> C –d–> D
Let h = a = b = c = d
Three hops (general_cutoff) RTTs = 3a + 2b + c RTTs = 6h Cannibalized: RTTs = a+b+c+d RTTs = 4h Four hops: RTTs = 4a + 3b + 2c + d RTTs = 10h Client INTRODUCE1+ACK: // XXX: correct? RTTs = 5a + 4b + 3c + 2d RTTs = 14h Server intro: RTTs = 4a + 3b + 2c RTTs = 9h
void circuit_expire_old_circs_as_needed | ( | time_t | now | ) |
Called once a second either directly or from circuit_build_needed_circs(). As appropriate (once per NewCircuitPeriod) resets failure counts and expires old circuits.
void circuit_expire_old_circuits_serverside | ( | time_t | now | ) |
Find each non-origin circuit that has been unused for too long, has no streams on it, came from a client, and ends here: mark it for close.
void circuit_expire_waiting_for_better_guard | ( | void | ) |
Mark for close all circuits that start here, that were built through a guard we weren't sure if we wanted to use, and that have been waiting around for way too long.
void circuit_has_opened | ( | origin_circuit_t * | circ | ) |
The circuit circ has just become open. Take the next step: for rendezvous circuits, we pass circ to the appropriate function in rendclient or rendservice. For general circuits, we call connection_ap_attach_pending, which looks for pending streams that could use circ.
origin_circuit_t* circuit_launch | ( | uint8_t | purpose, |
int | flags | ||
) |
Launch a new circuit; see circuit_launch_by_extend_info() for details on arguments.
origin_circuit_t* circuit_launch_by_extend_info | ( | uint8_t | purpose, |
extend_info_t * | extend_info, | ||
int | flags | ||
) |
Launch a new circuit with purpose purpose and exit node extend_info (or NULL to select a random exit node). If flags contains CIRCLAUNCH_NEED_UPTIME, choose among routers with high uptime. If CIRCLAUNCH_NEED_CAPACITY is set, choose among routers with high bandwidth. If CIRCLAUNCH_IS_INTERNAL is true, the last hop need not be an exit node. If CIRCLAUNCH_ONEHOP_TUNNEL is set, the circuit will have only one hop. Return the newly allocated circuit on success, or NULL on failure.
void circuit_log_ancient_one_hop_circuits | ( | int | age | ) |
As a diagnostic for bug 8387, log information about how many one-hop circuits we have around that have been there for at least age seconds. Log a few of them. Ignores Single Onion Service intro and Tor2web redezvous circuits, they are expected to be long-term one-hop circuits.
int circuit_purpose_is_hidden_service | ( | uint8_t | purpose | ) |
Tell us if a circuit is a hidden service circuit.
void circuit_read_valid_data | ( | origin_circuit_t * | circ, |
uint16_t | relay_body_len | ||
) |
Add relay_body_len and RELAY_PAYLOAD_SIZE-relay_body_len to the valid delivered read field and the overhead field, respectively.
void circuit_remove_handled_ports | ( | smartlist_t * | needed_ports | ) |
Remove any elements in needed_ports that are handled by an open or in-progress circuit.
void circuit_reset_failure_count | ( | int | timeout | ) |
Reset the failure count for opening general circuits. This means we will try MAX_CIRCUIT_FAILURES times more (if necessary) before stopping again.
void circuit_sent_valid_data | ( | origin_circuit_t * | circ, |
uint16_t | relay_body_len | ||
) |
Add relay_body_len and RELAY_PAYLOAD_SIZE-relay_body_len to the valid delivered written fields and the overhead field, respectively.
int circuit_should_use_vanguards | ( | uint8_t | purpose | ) |
Return true if this circuit purpose should use vanguards or pinned Layer2 or Layer3 guards.
This function takes both the circuit purpose and the torrc options for pinned middles/vanguards into account (ie: the circuit must be a hidden service circuit and vanguards/pinned middles must be enabled for it to return true).
int circuit_stream_is_being_handled | ( | entry_connection_t * | conn, |
uint16_t | port, | ||
int | min | ||
) |
Return 1 if at least min general-purpose non-internal circuits will have an acceptable exit node for exit stream conn if it is defined, else for "*:port". Else return 0.
void circuit_try_attaching_streams | ( | origin_circuit_t * | circ | ) |
Called when a circuit becomes ready for streams to be attached to it.
int connection_ap_handshake_attach_chosen_circuit | ( | entry_connection_t * | conn, |
origin_circuit_t * | circ, | ||
crypt_path_t * | cpath | ||
) |
Attempt to attach the connection conn to circ, and send a begin or resolve cell as appropriate. Return values are as for connection_ap_handshake_attach_circuit. The stream will exit from the hop indicated by cpath, or from the last hop in circ's cpath if cpath is NULL.
int connection_ap_handshake_attach_circuit | ( | entry_connection_t * | conn | ) |
Try to find a safe live circuit for stream conn. If we find one, attach the stream, send appropriate cells, and return 1. Otherwise, try to launch new circuit(s) for the stream. If we can launch circuits, return 0. Otherwise, if we simply can't proceed with this stream, return -1. (conn needs to die, and is maybe already marked).
int hostname_in_track_host_exits | ( | const or_options_t * | options, |
const char * | address | ||
) |
Return true iff address is matched by one of the entries in TrackHostExits.
void mark_circuit_unusable_for_new_conns | ( | origin_circuit_t * | circ | ) |
Mark circ so that no more connections can be attached to it.
void reset_bandwidth_test | ( | void | ) |
Reset have_performed_bandwidth_test, so we'll start building testing circuits again so we can exercise our bandwidth.