Data Structures | Macros | Typedefs | Functions | Variables
connection_or.c File Reference
#include "core/or/or.h"
#include "feature/client/bridges.h"
#include "lib/buf/buffers.h"
#include "core/or/channel.h"
#include "core/or/channeltls.h"
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
#include "core/or/circuitstats.h"
#include "core/or/command.h"
#include "app/config/config.h"
#include "core/mainloop/connection.h"
#include "core/or/connection_or.h"
#include "feature/control/control_events.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_util.h"
#include "feature/dirauth/reachability.h"
#include "feature/client/entrynodes.h"
#include "lib/geoip/geoip.h"
#include "core/mainloop/mainloop.h"
#include "trunnel/link_handshake.h"
#include "trunnel/netinfo.h"
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "core/proto/proto_cell.h"
#include "core/or/reasons.h"
#include "core/or/relay.h"
#include "feature/rend/rendcommon.h"
#include "feature/stats/rephist.h"
#include "feature/relay/router.h"
#include "feature/relay/routerkeys.h"
#include "feature/relay/routermode.h"
#include "feature/nodelist/dirlist.h"
#include "feature/nodelist/routerlist.h"
#include "feature/relay/ext_orport.h"
#include "core/or/scheduler.h"
#include "feature/nodelist/torcert.h"
#include "core/or/channelpadding.h"
#include "feature/dirauth/authmode.h"
#include "core/or/cell_st.h"
#include "core/or/cell_queue_st.h"
#include "core/or/or_connection_st.h"
#include "core/or/or_handshake_certs_st.h"
#include "core/or/or_handshake_state_st.h"
#include "app/config/or_state_st.h"
#include "feature/nodelist/routerinfo_st.h"
#include "core/or/var_cell_st.h"
#include "lib/crypt_ops/crypto_format.h"
#include "lib/tls/tortls.h"
#include "lib/tls/x509.h"
#include "core/or/orconn_event.h"

Go to the source code of this file.

Data Structures

struct  broken_state_count_t
struct  or_connect_failure_entry_t


#define TIME_BEFORE_OR_CONN_IS_TOO_OLD   (60*60*24*7)
#define certs_cell_ed25519_disabled_for_testing   0
#define testing__connection_or_pretend_TLSSECRET_is_supported   0


typedef struct broken_state_count_t broken_state_count_t
typedef struct or_connect_failure_entry_t or_connect_failure_entry_t


static int connection_tls_finish_handshake (or_connection_t *conn)
static int connection_or_launch_v3_or_handshake (or_connection_t *conn)
static int connection_or_process_cells_from_inbuf (or_connection_t *conn)
static int connection_or_check_valid_tls_handshake (or_connection_t *conn, int started_here, char *digest_rcvd_out)
static void connection_or_tls_renegotiated_cb (tor_tls_t *tls, void *_conn)
static unsigned int connection_or_is_bad_for_new_circs (or_connection_t *or_conn)
static void connection_or_mark_bad_for_new_circs (or_connection_t *or_conn)
static void connection_or_change_state (or_connection_t *conn, uint8_t state)
static void connection_or_check_canonicity (or_connection_t *conn, int started_here)
or_connection_tTO_OR_CONN (connection_t *c)
void connection_or_clear_identity (or_connection_t *conn)
void connection_or_clear_identity_map (void)
static void connection_or_set_identity_digest (or_connection_t *conn, const char *rsa_digest, const ed25519_public_key_t *ed_id)
void connection_or_remove_from_ext_or_id_map (or_connection_t *conn)
or_connection_tconnection_or_get_by_ext_or_id (const char *id)
void connection_or_clear_ext_or_id_map (void)
void connection_or_set_ext_or_identifier (or_connection_t *conn)
static void note_broken_connection (const char *state)
void clear_broken_connection_map (int stop_recording)
static void connection_or_get_state_description (or_connection_t *orconn, char *buf, size_t buflen)
static void connection_or_note_state_when_broken (or_connection_t *orconn)
static int broken_state_count_compare (const void **a_ptr, const void **b_ptr)
void connection_or_report_broken_states (int severity, int domain)
void connection_or_event_status (or_connection_t *conn, or_conn_status_event_t tp, int reason)
static void connection_or_state_publish (const or_connection_t *conn, uint8_t state)
 MOCK_IMPL (int, connection_or_get_num_circuits,(or_connection_t *conn))
void cell_pack (packed_cell_t *dst, const cell_t *src, int wide_circ_ids)
static void cell_unpack (cell_t *dest, const char *src, int wide_circ_ids)
int var_cell_pack_header (const var_cell_t *cell, char *hdr_out, int wide_circ_ids)
var_cell_tvar_cell_new (uint16_t payload_len)
var_cell_tvar_cell_copy (const var_cell_t *src)
void var_cell_free_ (var_cell_t *cell)
int connection_or_reached_eof (or_connection_t *conn)
int connection_or_process_inbuf (or_connection_t *conn)
int connection_or_flushed_some (or_connection_t *conn)
ssize_t connection_or_num_cells_writeable (or_connection_t *conn)
int connection_or_finished_flushing (or_connection_t *conn)
int connection_or_finished_connecting (or_connection_t *or_conn)
void connection_or_about_to_close (or_connection_t *or_conn)
int connection_or_digest_is_known_relay (const char *id_digest)
static void connection_or_update_token_buckets_helper (or_connection_t *conn, int reset, const or_options_t *options)
void connection_or_update_token_buckets (smartlist_t *conns, const or_options_t *options)
void connection_or_set_canonical (or_connection_t *or_conn, int is_canonical)
void connection_or_init_conn_from_address (or_connection_t *conn, const tor_addr_t *addr, uint16_t port, const char *id_digest, const ed25519_public_key_t *ed_id, int started_here)
int connection_or_single_set_badness_ (time_t now, or_connection_t *or_conn, int force)
void connection_or_group_set_badness_ (smartlist_t *group, int force)
static HT_HEAD (or_connect_failure_ht, or_connect_failure_entry_t)
static unsigned int or_connect_failure_ht_hash (const or_connect_failure_entry_t *entry)
 HT_PROTOTYPE (HT_GENERATE2(or_connect_failure_ht, HT_GENERATE2(or_connect_failure_entry_t, HT_GENERATE2(node, HT_GENERATE2(or_connect_failure_ht_hash, HT_GENERATE2(or_connect_failure_ht_eq)
static or_connect_failure_entry_tor_connect_failure_new (const or_connection_t *or_conn)
static or_connect_failure_entry_tor_connect_failure_find (const or_connection_t *or_conn)
STATIC void note_or_connect_failed (const or_connection_t *or_conn)
static void or_connect_failure_map_cleanup (time_t cutoff)
STATIC int should_connect_to_relay (const or_connection_t *or_conn)
void connection_or_connect_failed (or_connection_t *conn, int reason, const char *msg)
void connection_or_notify_error (or_connection_t *conn, int reason, const char *msg)
 MOCK_IMPL (or_connection_t *, connection_or_connect,(const tor_addr_t *_addr, uint16_t port, const char *id_digest, const ed25519_public_key_t *ed_id, channel_tls_t *chan))
void connection_or_close_normally (or_connection_t *orconn, int flush)
 MOCK_IMPL (void, connection_or_close_for_error,(or_connection_t *orconn, int flush))
 MOCK_IMPL (int, connection_tls_start_handshake,(or_connection_t *conn, int receiving))
void connection_or_block_renegotiation (or_connection_t *conn)
int connection_tls_continue_handshake (or_connection_t *conn)
int connection_or_nonopen_was_started_here (or_connection_t *conn)
int connection_or_client_learned_peer_id (or_connection_t *conn, const uint8_t *rsa_peer_id, const ed25519_public_key_t *ed_peer_id)
time_t connection_or_client_used (or_connection_t *conn)
int connection_init_or_handshake_state (or_connection_t *conn, int started_here)
void or_handshake_state_free_ (or_handshake_state_t *state)
void or_handshake_state_record_cell (or_connection_t *conn, or_handshake_state_t *state, const cell_t *cell, int incoming)
void or_handshake_state_record_var_cell (or_connection_t *conn, or_handshake_state_t *state, const var_cell_t *cell, int incoming)
int connection_or_set_state_open (or_connection_t *conn)
void connection_or_write_cell_to_buf (const cell_t *cell, or_connection_t *conn)
 MOCK_IMPL (void, connection_or_write_var_cell_to_buf,(const var_cell_t *cell, or_connection_t *conn))
static int connection_fetch_var_cell_from_buf (or_connection_t *or_conn, var_cell_t **out)
int is_or_protocol_version_known (uint16_t v)
int connection_or_send_versions (or_connection_t *conn, int v3_plus)
static netinfo_addr_t * netinfo_addr_from_tor_addr (const tor_addr_t *tor_addr)
 MOCK_IMPL (int, connection_or_send_netinfo,(or_connection_t *conn))
static void add_certs_cell_cert_helper (certs_cell_t *certs_cell, uint8_t cert_type, const uint8_t *cert_encoded, size_t cert_len)
static void add_x509_cert (certs_cell_t *certs_cell, uint8_t cert_type, const tor_x509_cert_t *cert)
static void add_ed25519_cert (certs_cell_t *certs_cell, uint8_t cert_type, const tor_cert_t *cert)
int connection_or_send_certs_cell (or_connection_t *conn)
int authchallenge_type_is_supported (uint16_t challenge_type)
int authchallenge_type_is_better (uint16_t challenge_type_a, uint16_t challenge_type_b)
int connection_or_send_auth_challenge_cell (or_connection_t *conn)
var_cell_tconnection_or_compute_authenticate_cell_body (or_connection_t *conn, const int authtype, crypto_pk_t *signing_key, const ed25519_keypair_t *ed_signing_key, int server)
 MOCK_IMPL (int, connection_or_send_authenticate_cell,(or_connection_t *conn, int authtype))


static digestmap_t * orconn_ext_or_id_map = NULL
static strmap_t * broken_connection_counts
static int disable_broken_connection_counts = 0
static time_t or_connect_failure_map_next_cleanup_ts = 0
static const uint16_t or_protocol_versions [] = { 1, 2, 3, 4, 5 }
static const int n_or_protocol_versions

Detailed Description

Functions to handle OR connections, TLS handshaking, and cells on the network.

An or_connection_t is a subtype of connection_t (as implemented in connection.c) that uses a TLS connection to send and receive cells on the Tor network. (By sending and receiving cells connection_or.c, it cooperates with channeltls.c to implement a the channel interface of channel.c.)

Every OR connection has an underlying tortls_t object (as implemented in tortls.c) which it uses as its TLS stream. It is responsible for sending and receiving cells over that TLS.

This module also implements the client side of the v3 Tor link handshake,

Definition in file connection_or.c.

Macro Definition Documentation



Upper limit on the number of different states to report for connection failure.

Definition at line 369 of file connection_or.c.


#define TIME_BEFORE_OR_CONN_IS_TOO_OLD   (60*60*24*7)

How old do we let a connection to an OR get before deciding it's too old for new circuits?

Definition at line 1038 of file connection_or.c.

Typedef Documentation

◆ broken_state_count_t

Helper type used to sort connection states and find the most frequent.

Function Documentation

◆ add_certs_cell_cert_helper()

static void add_certs_cell_cert_helper ( certs_cell_t *  certs_cell,
uint8_t  cert_type,
const uint8_t *  cert_encoded,
size_t  cert_len 

Helper used to add an encoded certs to a cert cell

Definition at line 2596 of file connection_or.c.

References tor_assert().

Referenced by add_ed25519_cert(), and add_x509_cert().

◆ add_ed25519_cert()

static void add_ed25519_cert ( certs_cell_t *  certs_cell,
uint8_t  cert_type,
const tor_cert_t cert 

Add an Ed25519 cert from cert to the trunnel certs_cell_t object that we are building in certs_cell. Set its type field to cert_type. (If cert is NULL, take no action.)

Definition at line 2634 of file connection_or.c.

References add_certs_cell_cert_helper(), tor_cert_st::encoded, and tor_cert_st::encoded_len.

◆ add_x509_cert()

static void add_x509_cert ( certs_cell_t *  certs_cell,
uint8_t  cert_type,
const tor_x509_cert_t *  cert 

Add an encoded X509 cert (stored as cert_len bytes at cert_encoded) to the trunnel certs_cell_t object that we are building in certs_cell. Set its type field to cert_type. (If cert is NULL, take no action.)

Definition at line 2616 of file connection_or.c.

References add_certs_cell_cert_helper(), and tor_x509_cert_get_der().

◆ authchallenge_type_is_better()

int authchallenge_type_is_better ( uint16_t  challenge_type_a,
uint16_t  challenge_type_b 

Return true iff challenge_type_a is one that we would rather use than challenge_type_b.

Definition at line 2772 of file connection_or.c.

References authchallenge_type_is_supported().

◆ authchallenge_type_is_supported()

int authchallenge_type_is_supported ( uint16_t  challenge_type)

Return true iff challenge_type is an AUTHCHALLENGE type that we can send and receive.

Definition at line 2752 of file connection_or.c.


Referenced by authchallenge_type_is_better(), and connection_or_send_auth_challenge_cell().

◆ broken_state_count_compare()

static int broken_state_count_compare ( const void **  a_ptr,
const void **  b_ptr 

Helper function used to sort broken_state_count_t by frequency.

Definition at line 356 of file connection_or.c.

◆ cell_pack()

void cell_pack ( packed_cell_t dst,
const cell_t src,
int  wide_circ_ids 

Pack the cell_t host-order structure src into network-order in the buffer dest. See tor-spec.txt for details about the wire format.

Note that this function doesn't touch dst->next: the caller should set it or clear it as appropriate.

Definition at line 496 of file connection_or.c.

References packed_cell_t::body, CELL_MAX_NETWORK_SIZE, cell_t::circ_id, set_uint16(), and set_uint32().

Referenced by packed_cell_copy().

◆ cell_unpack()

static void cell_unpack ( cell_t dest,
const char *  src,
int  wide_circ_ids 

Unpack the network-order buffer src into a host-order cell_t structure dest.

Definition at line 517 of file connection_or.c.

References cell_t::circ_id, cell_t::command, get_uint16(), and get_uint32().

◆ clear_broken_connection_map()

void clear_broken_connection_map ( int  stop_recording)

Forget all recorded states for failed connections. If stop_recording is true, don't record any more.

Definition at line 306 of file connection_or.c.

References broken_connection_counts.

Referenced by connection_free_all().

◆ connection_fetch_var_cell_from_buf()

static int connection_fetch_var_cell_from_buf ( or_connection_t or_conn,
var_cell_t **  out 

See whether there's a variable-length cell waiting on or_conn's inbuf. Return values as for fetch_var_cell_from_buf().

Definition at line 2360 of file connection_or.c.

References connection_t::inbuf, or_connection_t::link_proto, and TO_CONN.

◆ connection_init_or_handshake_state()

int connection_init_or_handshake_state ( or_connection_t conn,
int  started_here 

Allocate a new connection handshake state for the connection conn. Return 0 on success, -1 on failure.

Definition at line 2160 of file connection_or.c.

References or_connection_t::handshake_state.

Referenced by connection_or_launch_v3_or_handshake().

◆ connection_or_about_to_close()

void connection_or_about_to_close ( or_connection_t or_conn)

Called when we're about to finally unlink and free an OR connection: perform necessary accounting and cleanup

Definition at line 784 of file connection_or.c.

References or_connection_t::chan, channel_closed(), and TO_CONN.

Referenced by connection_about_to_close_connection().

◆ connection_or_block_renegotiation()

void connection_or_block_renegotiation ( or_connection_t conn)

Block all future attempts to renegotiate on 'conn'

Definition at line 1703 of file connection_or.c.

References or_connection_t::tls, tor_tls_block_renegotiation(), and tor_tls_set_renegotiate_callback().

Referenced by connection_or_tls_renegotiated_cb().

◆ connection_or_change_state()

static void connection_or_change_state ( or_connection_t conn,
uint8_t  state 

◆ connection_or_check_canonicity()

static void connection_or_check_canonicity ( or_connection_t conn,
int  started_here 

Check whether the identity of conn matches a known node. If it does, check whether the address of conn matches the expected address, and update the connection's is_canonical flag, nickname, and address fields as appropriate.

Definition at line 951 of file connection_or.c.

References or_connection_t::chan, or_connection_t::identity_digest, and or_connection_t::real_addr.

◆ connection_or_check_valid_tls_handshake()

static int connection_or_check_valid_tls_handshake ( or_connection_t conn,
int  started_here,
char *  digest_rcvd_out 

Conn just completed its handshake. Return 0 if all is well, and return -1 if they are lying, broken, or otherwise something is wrong.

If we initiated this connection (started_here is true), make sure the other side sent a correctly formed certificate. If I initiated the connection, make sure it's the right relay by checking the certificate.

Otherwise (if we didn't initiate this connection), it's okay for the certificate to be weird or absent.

If we return 0, and the certificate is as expected, write a hash of the identity key into digest_rcvd_out, which must have DIGEST_LEN space in it. If the certificate is invalid or missing on an incoming connection, we return 0 and set digest_rcvd_out to DIGEST_LEN NUL bytes. (If we return -1, the contents of this buffer are undefined.)

As side effects, 1) Set conn->circ_id_type according to tor-spec.txt. 2) If we're an authdirserver and we initiated the connection: drop all descriptors that claim to be on that IP/port but that aren't this relay; and note that this relay is reachable. 3) If this is a bridge and we didn't configure its identity fingerprint, remember the keyid we just learned.

Definition at line 1827 of file connection_or.c.

◆ connection_or_clear_ext_or_id_map()

void connection_or_clear_ext_or_id_map ( void  )

Deallocate the global Extended ORPort identifier list

Definition at line 239 of file connection_or.c.

Referenced by connection_free_all().

◆ connection_or_clear_identity()

void connection_or_clear_identity ( or_connection_t conn)

Clear clear conn->identity_digest and update other data structures as appropriate.

Definition at line 126 of file connection_or.c.

References DIGEST_LEN, or_connection_t::identity_digest, and tor_assert().

Referenced by connection_unlink().

◆ connection_or_clear_identity_map()

void connection_or_clear_identity_map ( void  )

Clear all identities in OR conns.

Definition at line 134 of file connection_or.c.


Referenced by connection_free_all().

◆ connection_or_client_learned_peer_id()

int connection_or_client_learned_peer_id ( or_connection_t conn,
const uint8_t *  rsa_peer_id,
const ed25519_public_key_t ed_peer_id 

Called when we (as a connection initiator) have definitively, authenticatedly, learned that ID of the Tor instance on the other side of conn is rsa_peer_id and optionally ed_peer_id. For v1 and v2 handshakes, this is right after we get a certificate chain in a TLS handshake or renegotiation. For v3+ handshakes, this is right after we get a certificate chain in a CERTS cell.

If we did not know the ID before, record the one we got.

If we wanted an ID, but we didn't get the one we expected, log a message and return -1. On relays:

  • log a protocol warning whenever the fingerprints don't match; On clients:
  • if a relay's fingerprint doesn't match, log a warning;
  • if we don't have updated relay fingerprints from a recent consensus, and a fallback directory mirror's hard-coded fingerprint has changed, log an info explaining that we will try another fallback.

If we're testing reachability, remember what we learned.

Return 0 on success, -1 on failure.

Definition at line 1924 of file connection_or.c.

References or_connection_t::chan, channel_tls_to_base(), channel_s::ed25519_identity, ed25519_public_key_is_zero(), or_connection_t::identity_digest, tor_assert(), and tor_digest_is_zero().

◆ connection_or_client_used()

time_t connection_or_client_used ( or_connection_t conn)

Return when we last used this channel for client activity (origin circuits). This is called from connection.c, since client_used is now one of the timestamps in channel_t

Definition at line 2075 of file connection_or.c.

References or_connection_t::chan, channel_when_last_client(), and tor_assert().

Referenced by connection_counts_as_relayed_traffic().

◆ connection_or_close_normally()

void connection_or_close_normally ( or_connection_t orconn,
int  flush 

Mark orconn for close and transition the associated channel, if any, to the closing state.

It's safe to call this and connection_or_close_for_error() any time, and channel layer will treat it as a connection closing for reasons outside its control, like the remote end closing it. It can also be a local reason that's specific to connection_t/or_connection_t rather than the channel mechanism, such as expiration of old connections in run_connection_housekeeping(). If you want to close a channel_t from somewhere that logically works in terms of generic channels rather than connections, use channel_mark_for_close(); see also the comment on that function in channel.c.

Definition at line 1616 of file connection_or.c.

References tor_assert().

◆ connection_or_compute_authenticate_cell_body()

var_cell_t* connection_or_compute_authenticate_cell_body ( or_connection_t conn,
const int  authtype,
crypto_pk_t signing_key,
const ed25519_keypair_t ed_signing_key,
int  server 

Compute the main body of an AUTHENTICATE cell that a client can use to authenticate itself on a v3 handshake for conn. Return it in a var_cell_t.

If server is true, only calculate the first V3_AUTH_FIXED_PART_LEN bytes – the part of the authenticator that's determined by the rest of the handshake, and which match the provided value exactly.

If server is false and signing_key is NULL, calculate the first V3_AUTH_BODY_LEN bytes of the authenticator (that is, everything that should be signed), but don't actually sign it.

If server is false and signing_key is provided, calculate the entire authenticator, signed with signing_key.

Return the length of the cell body on success, and -1 on failure.

Definition at line 2853 of file connection_or.c.

References AUTHTYPE_ED25519_SHA256_RFC5705, AUTHTYPE_RSA_SHA256_RFC5705, AUTHTYPE_RSA_SHA256_TLSSECRET, or_handshake_state_t::certs, or_connection_t::handshake_state, or_handshake_certs_t::id_cert, tor_assert(), tor_tls_get_my_certs(), and tor_x509_cert_get_id_digests().

◆ connection_or_connect_failed()

void connection_or_connect_failed ( or_connection_t conn,
int  reason,
const char *  msg 

conn is in the 'connecting' state, and it failed to complete a TCP connection. Send notifications appropriately.

reason specifies the or_conn_end_reason for the failure; msg specifies the strerror-style error message.

Definition at line 1412 of file connection_or.c.

References connection_or_event_status().

Referenced by connection_or_notify_error().

◆ connection_or_digest_is_known_relay()

int connection_or_digest_is_known_relay ( const char *  id_digest)

Return 1 if identity digest id_digest is known to be a currently or recently running relay. Otherwise return 0.

Definition at line 831 of file connection_or.c.

References router_get_by_id_digest(), and router_get_consensus_status_by_id().

Referenced by connection_or_update_token_buckets_helper().

◆ connection_or_event_status()

void connection_or_event_status ( or_connection_t conn,
or_conn_status_event_t  tp,
int  reason 

Helper function to publish an OR connection status event

Publishes a messages to subscribers of ORCONN messages, and sends the control event.

Definition at line 414 of file connection_or.c.

Referenced by connection_ext_or_transition(), connection_init_accepted_conn(), connection_or_connect_failed(), and connection_or_set_state_open().

◆ connection_or_finished_connecting()

int connection_or_finished_connecting ( or_connection_t or_conn)

Connected handler for OR connections: begin the TLS handshake.

Definition at line 749 of file connection_or.c.

References OR_CONN_STATE_CONNECTING, or_connection_t::proxy_type, connection_t::state, TO_CONN, and tor_assert().

Referenced by connection_finished_connecting().

◆ connection_or_finished_flushing()

int connection_or_finished_flushing ( or_connection_t conn)

Connection conn has finished writing and has no bytes left on its outbuf.

Otherwise it's in state "open": stop writing and return.

If conn is broken, mark it for close and return -1, else return 0.

Definition at line 722 of file connection_or.c.

References assert_connection_ok(), OR_CONN_STATE_OPEN, OR_CONN_STATE_OR_HANDSHAKING_V2, OR_CONN_STATE_OR_HANDSHAKING_V3, OR_CONN_STATE_PROXY_HANDSHAKING, connection_t::state, TO_CONN, and tor_assert().

Referenced by connection_finished_flushing().

◆ connection_or_flushed_some()

int connection_or_flushed_some ( or_connection_t conn)

Called whenever we have flushed some data on an or_conn: add more data from active circuits.

Definition at line 670 of file connection_or.c.

References or_connection_t::chan, and channel_timestamp_active().

Referenced by connection_flushed_some().

◆ connection_or_get_by_ext_or_id()

or_connection_t* connection_or_get_by_ext_or_id ( const char *  id)

Return the connection whose ext_or_id is id. Return NULL if no such connection is found.

Definition at line 230 of file connection_or.c.

References orconn_ext_or_id_map.

◆ connection_or_get_state_description()

static void connection_or_get_state_description ( or_connection_t orconn,
char *  buf,
size_t  buflen 

Write a detailed description the state of orconn into the buflen-byte buffer at buf. This description includes not only the OR-conn level state but also the TLS state. It's useful for diagnosing broken handshakes.

Definition at line 320 of file connection_or.c.

References conn_state_to_string(), CONN_TYPE_EXT_OR, CONN_TYPE_OR, connection_t::state, or_connection_t::tls, TO_CONN, tor_assert(), tor_snprintf(), tor_tls_get_state_description(), and connection_t::type.

Referenced by connection_or_note_state_when_broken().

◆ connection_or_group_set_badness_()

void connection_or_group_set_badness_ ( smartlist_t group,
int  force 

Given a list of all the or_connections with a given identity, set elements of that list as is_bad_for_new_circs as appropriate. Helper for connection_or_set_bad_connections().

Specifically, we set the is_bad_for_new_circs flag on:

  • all connections if force is true.
  • all connections that are too old.
  • all open non-canonical connections for which a canonical connection exists to the same router.
  • all open canonical connections for which a 'better' canonical connection exists to the same router.
  • all open non-canonical connections for which a 'better' non-canonical connection exists to the same router at the same address.

See channel_is_better() in channel.c for our idea of what makes one OR connection better than another.

Definition at line 1088 of file connection_or.c.

References connection_or_is_bad_for_new_circs(), connection_or_single_set_badness_(), or_connection_t::is_canonical, OR_CONN_STATE_OPEN, SMARTLIST_FOREACH_BEGIN, and connection_t::state.

◆ connection_or_init_conn_from_address()

void connection_or_init_conn_from_address ( or_connection_t conn,
const tor_addr_t addr,
uint16_t  port,
const char *  id_digest,
const ed25519_public_key_t ed_id,
int  started_here 

If we don't necessarily know the router we're connecting to, but we have an addr/port/id_digest, then fill in as much as we can. Start by checking to see if this describes a router we know. started_here is 1 if we are the initiator of conn and 0 if it's an incoming connection.

Definition at line 924 of file connection_or.c.

◆ connection_or_is_bad_for_new_circs()

static unsigned int connection_or_is_bad_for_new_circs ( or_connection_t or_conn)

These just pass all the is_bad_for_new_circs manipulation on to channel_t

Definition at line 1018 of file connection_or.c.

References or_connection_t::chan, channel_is_bad_for_new_circs(), and tor_assert().

Referenced by connection_or_group_set_badness_(), and connection_or_single_set_badness_().

◆ connection_or_launch_v3_or_handshake()

static int connection_or_launch_v3_or_handshake ( or_connection_t conn)

Called as client when initial TLS handshake is done, and we notice that we got a v3-handshake signalling certificate from the server. Set up structures, do bookkeeping, and send the versions cell. Return 0 on success and -1 on failure.

Definition at line 2144 of file connection_or.c.

References circuit_build_times_network_is_live(), connection_init_or_handshake_state(), connection_or_change_state(), connection_or_nonopen_was_started_here(), connection_or_send_versions(), get_circuit_build_times_mutable(), OR_CONN_STATE_OR_HANDSHAKING_V3, and tor_assert().

◆ connection_or_nonopen_was_started_here()

int connection_or_nonopen_was_started_here ( or_connection_t conn)

◆ connection_or_note_state_when_broken()

static void connection_or_note_state_when_broken ( or_connection_t orconn)

Record the current state of orconn as the state of a broken connection.

Definition at line 338 of file connection_or.c.

References connection_or_get_state_description(), and disable_broken_connection_counts.

◆ connection_or_notify_error()

void connection_or_notify_error ( or_connection_t conn,
int  reason,
const char *  msg 

conn got an error in connection_handle_read_impl() or connection_handle_write_impl() and is going to die soon.

reason specifies the or_conn_end_reason for the failure; msg specifies the strerror-style error message.

Definition at line 1428 of file connection_or.c.

References or_connection_t::chan, connection_or_connect_failed(), OR_CONN_STATE_CONNECTING, TO_CONN, and tor_assert().

Referenced by connection_handle_read_impl().

◆ connection_or_num_cells_writeable()

ssize_t connection_or_num_cells_writeable ( or_connection_t conn)

This is for channeltls.c to ask how many cells we could accept if they were available.

Definition at line 692 of file connection_or.c.

References tor_assert().

◆ connection_or_process_cells_from_inbuf()

static int connection_or_process_cells_from_inbuf ( or_connection_t conn)

Process cells from conn's inbuf.

Loop: while inbuf contains a cell, pull it off the inbuf, unpack it, and hand it to command_process_cell().

Always return 0.

Definition at line 2374 of file connection_or.c.

◆ connection_or_process_inbuf()

int connection_or_process_inbuf ( or_connection_t conn)

Handle any new bytes that have come in on connection conn. If conn is in 'open' state, hand it to connection_or_process_cells_from_inbuf() (else do nothing).

Don't let the inbuf of a nonopen OR connection grow beyond this many bytes: it's either a broken client, a non-Tor client, or a DOS attempt.

Definition at line 610 of file connection_or.c.

References connection_read_proxy_handshake(), OR_CONN_STATE_PROXY_HANDSHAKING, connection_t::state, TO_CONN, and tor_assert().

Referenced by connection_process_inbuf().

◆ connection_or_reached_eof()

int connection_or_reached_eof ( or_connection_t conn)

We've received an EOF from conn. Mark it for close and return.

Definition at line 594 of file connection_or.c.

References tor_assert().

Referenced by connection_reached_eof().

◆ connection_or_remove_from_ext_or_id_map()

void connection_or_remove_from_ext_or_id_map ( or_connection_t conn)

Remove the Extended ORPort identifier of conn from the global identifier list. Also, clear the identifier from the connection itself.

Definition at line 212 of file connection_or.c.

References or_connection_t::ext_or_conn_id, EXT_OR_CONN_ID_LEN, orconn_ext_or_id_map, tor_assert(), and tor_digest_is_zero().

Referenced by connection_or_set_ext_or_identifier().

◆ connection_or_report_broken_states()

void connection_or_report_broken_states ( int  severity,
int  domain 

Report a list of the top states for failed OR connections at log level severity, in log domain domain.

Definition at line 374 of file connection_or.c.

References broken_connection_counts, and disable_broken_connection_counts.

◆ connection_or_send_auth_challenge_cell()

int connection_or_send_auth_challenge_cell ( or_connection_t conn)

◆ connection_or_send_certs_cell()

int connection_or_send_certs_cell ( or_connection_t conn)

Send a CERTS cell on the connection conn. Return 0 on success, -1 on failure.

Definition at line 2654 of file connection_or.c.

References or_connection_t::handshake_state, OR_CONN_STATE_OR_HANDSHAKING_V3, or_handshake_state_t::started_here, connection_t::state, or_connection_t::tls, tor_assert(), and tor_tls_get_my_certs().

◆ connection_or_send_versions()

int connection_or_send_versions ( or_connection_t conn,
int  v3_plus 

Send a VERSIONS cell on conn, telling the other host about the link protocol versions that this Tor can support.

If v3_plus, this is part of a V3 protocol handshake, so only allow protocol version v3 or later. If not v3_plus, this is not part of a v3 protocol handshake, so don't allow protocol v3 or later.

Definition at line 2461 of file connection_or.c.

References var_cell_t::command, or_connection_t::handshake_state, n_or_protocol_versions, or_handshake_state_t::sent_versions_at, tor_assert(), and var_cell_new().

Referenced by connection_or_launch_v3_or_handshake().

◆ connection_or_set_ext_or_identifier()

void connection_or_set_ext_or_identifier ( or_connection_t conn)

Creates an Extended ORPort identifier for conn and deposits it into the global list of identifiers.

Definition at line 248 of file connection_or.c.

References connection_or_remove_from_ext_or_id_map(), or_connection_t::ext_or_conn_id, EXT_OR_CONN_ID_LEN, orconn_ext_or_id_map, and tor_digest_is_zero().

◆ connection_or_set_identity_digest()

static void connection_or_set_identity_digest ( or_connection_t conn,
const char *  rsa_digest,
const ed25519_public_key_t ed_id 

Change conn->identity_digest to digest, and add conn into the appropriate digest maps.

NOTE that this function only allows two kinds of transitions: from unset identity to set identity, and from idempotent re-settings of the same identity. It's not allowed to clear an identity or to change an identity. Return 0 on success, and -1 if the transition is not allowed.

Definition at line 155 of file connection_or.c.

References or_connection_t::chan, and tor_assert().

◆ connection_or_set_state_open()

int connection_or_set_state_open ( or_connection_t conn)

Set conn's state to OR_CONN_STATE_OPEN, and tell other subsystems as appropriate. Called when we are done with all TLS and OR handshaking.

Definition at line 2276 of file connection_or.c.

References connection_or_change_state(), connection_or_event_status(), and OR_CONN_STATE_OPEN.

◆ connection_or_single_set_badness_()

int connection_or_single_set_badness_ ( time_t  now,
or_connection_t or_conn,
int  force 

Expire an or_connection if it is too old. Helper for connection_or_group_set_badness_ and fast path for channel_rsa_id_group_set_badness.

Returns 1 if the connection was already expired, else 0.

Definition at line 1047 of file connection_or.c.

References connection_or_is_bad_for_new_circs(), connection_t::marked_for_close, TIME_BEFORE_OR_CONN_IS_TOO_OLD, and connection_t::timestamp_created.

Referenced by connection_or_group_set_badness_().

◆ connection_or_state_publish()

static void connection_or_state_publish ( const or_connection_t conn,
uint8_t  state 

Helper function to publish a state change message

connection_or_change_state() calls this to notify subscribers about a change of an OR connection state.

Definition at line 433 of file connection_or.c.

Referenced by connection_or_change_state().

◆ connection_or_tls_renegotiated_cb()

static void connection_or_tls_renegotiated_cb ( tor_tls_t tls,
void *  _conn 

Invoked on the server side from inside tor_tls_read() when the server gets a successful TLS renegotiation from the client.

Definition at line 1715 of file connection_or.c.

References connection_or_block_renegotiation(), and connection_tls_finish_handshake().

◆ connection_or_update_token_buckets()

void connection_or_update_token_buckets ( smartlist_t conns,
const or_options_t options 

Either our set of relays or our per-conn rate limits have changed. Go through all the OR connections and update their token buckets to make sure they don't exceed their maximum values.

Definition at line 883 of file connection_or.c.


◆ connection_or_update_token_buckets_helper()

static void connection_or_update_token_buckets_helper ( or_connection_t conn,
int  reset,
const or_options_t options 

Set the per-conn read and write limits for conn. If it's a known relay, we will rely on the global read and write buckets, so give it per-conn limits that are big enough they'll never matter. But if it's not a known relay, first check if we set PerConnBwRate/Burst, then check if the consensus sets them, else default to 'big enough'.

If reset is true, set the bucket to be full. Otherwise, just clip the bucket if it happens to be too full.

Definition at line 851 of file connection_or.c.

References or_options_t::BandwidthBurst, or_options_t::BandwidthRate, or_connection_t::bucket, connection_or_digest_is_known_relay(), or_connection_t::identity_digest, monotime_coarse_get_stamp(), or_options_t::PerConnBWBurst, or_options_t::PerConnBWRate, token_bucket_rw_adjust(), and token_bucket_rw_reset().

◆ connection_or_write_cell_to_buf()

void connection_or_write_cell_to_buf ( const cell_t cell,
or_connection_t conn 

Pack cell into wire-format, and write it onto conn's outbuf. For cells that use or affect a circuit, this should only be called by connection_or_flush_from_first_active_circuit().

Definition at line 2299 of file connection_or.c.

◆ connection_tls_continue_handshake()

int connection_tls_continue_handshake ( or_connection_t conn)

Move forward with the tls handshake. If it finishes, hand conn to connection_tls_finish_handshake().

Return -1 if conn is broken, else return 0.

Definition at line 1736 of file connection_or.c.

◆ connection_tls_finish_handshake()

static int connection_tls_finish_handshake ( or_connection_t conn)

The v1/v2 TLS handshake is finished.

Make sure we are happy with the peer we just handshaked with.

If they initiated the connection, make sure they're not already connected, then initialize conn from the information in router.

If all is successful, call circuit_n_conn_done() to handle events that have been pending on the <tls handshake completion. Also set the directory to be dirty (only matters if I'm an authdirserver).

If this is a v2 TLS handshake, send a versions cell.

Definition at line 2098 of file connection_or.c.

References connection_or_nonopen_was_started_here(), DIGEST_LEN, and tor_assert().

Referenced by connection_or_tls_renegotiated_cb().

◆ is_or_protocol_version_known()

int is_or_protocol_version_known ( uint16_t  v)

Return true iff v is a link protocol version that this Tor implementation believes it can support.

Definition at line 2442 of file connection_or.c.

References n_or_protocol_versions, and or_protocol_versions.

◆ MOCK_IMPL() [1/7]

MOCK_IMPL ( int  ,
connection_or_get_num_circuits  ,
(or_connection_t *conn)   

Return the number of circuits using an or_connection_t; this used to be an or_connection_t field, but it got moved to channel_t and we shouldn't maintain two copies.

Definition at line 476 of file connection_or.c.

References or_connection_t::chan, channel_num_circuits(), and tor_assert().

◆ MOCK_IMPL() [2/7]

MOCK_IMPL ( or_connection_t ,
connection_or_connect  ,
(const tor_addr_t *_addr, uint16_t port, const char *id_digest, const ed25519_public_key_t *ed_id, channel_tls_t *chan)   

Launch a new OR connection to addr:port and expect to handshake with an OR with identity digest id_digest. Optionally, pass in a pointer to a channel using this connection.

If id_digest is me, do nothing. If we're already connected to it, return that connection. If the connect() is in progress, set the new conn's state to 'connecting' and return it. If connect() succeeds, call connection_tls_start_handshake() on it.

This function is called from router_retry_connections(), for ORs connecting to ORs, and circuit_establish_circuit(), for OPs connecting to ORs.

Return the launched conn, or NULL if it failed.

Definition at line 1467 of file connection_or.c.

References router_digest_is_me(), tor_addr_copy(), and tor_assert().

◆ MOCK_IMPL() [3/7]

MOCK_IMPL ( void  ,
connection_or_close_for_error  ,
(or_connection_t *orconn, int flush)   

Mark orconn for close and transition the associated channel, if any, to the error state.

Definition at line 1636 of file connection_or.c.

References tor_assert().

◆ MOCK_IMPL() [4/7]

MOCK_IMPL ( int  ,
connection_tls_start_handshake  ,
(or_connection_t *conn, int receiving)   

Begin the tls handshake with conn. receiving is 0 if we initiated the connection, else it's 1.

Assign a new tls object to conn->tls, begin reading on conn, and pass conn to connection_tls_continue_handshake().

Return -1 if conn is broken, else return 0.

Definition at line 1661 of file connection_or.c.

References or_connection_t::chan, channel_listener_queue_incoming(), channel_tls_get_listener(), channel_tls_handle_incoming(), channel_tls_start_listener(), command_setup_listener(), connection_or_change_state(), OR_CONN_STATE_TLS_HANDSHAKING, connection_t::s, or_connection_t::tls, tor_assert(), and tor_tls_new().

◆ MOCK_IMPL() [5/7]

MOCK_IMPL ( void  ,
connection_or_write_var_cell_to_buf  ,
(const var_cell_t *cell, or_connection_t *conn)   

Pack a variable-length cell into wire-format, and write it onto conn's outbuf. Right now, this DOES NOT support cells that affect a circuit.

Definition at line 2336 of file connection_or.c.

References tor_assert(), VAR_CELL_MAX_HEADER_SIZE, and var_cell_pack_header().

◆ MOCK_IMPL() [6/7]

MOCK_IMPL ( int  ,
connection_or_send_netinfo  ,
(or_connection_t *conn)   

Send a NETINFO cell on conn, telling the other server what we know about their address, our address, and the current time.

Definition at line 2515 of file connection_or.c.

References or_connection_t::handshake_state, and tor_assert().

◆ MOCK_IMPL() [7/7]

MOCK_IMPL ( int  ,
connection_or_send_authenticate_cell  ,
(or_connection_t *conn, int authtype)   

Send an AUTHENTICATE cell on the connection conn. Return 0 on success, -1 on failure

Definition at line 3092 of file connection_or.c.

References tor_tls_get_my_client_auth_key().

◆ note_broken_connection()

static void note_broken_connection ( const char *  state)

Record that an OR connection failed in state.

Definition at line 286 of file connection_or.c.

References broken_connection_counts, and disable_broken_connection_counts.

◆ or_handshake_state_free_()

void or_handshake_state_free_ ( or_handshake_state_t state)

Free all storage held by state.

Definition at line 2181 of file connection_or.c.

◆ or_handshake_state_record_cell()

void or_handshake_state_record_cell ( or_connection_t conn,
or_handshake_state_t state,
const cell_t cell,
int  incoming 

Remember that cell has been transmitted (if incoming is false) or received (if incoming is true) during a V3 handshake using state.

(We don't record the cell, but we keep a digest of everything sent or received during the v3 handshake, and the client signs it in an authenticate cell.)

Definition at line 2203 of file connection_or.c.

◆ or_handshake_state_record_var_cell()

void or_handshake_state_record_var_cell ( or_connection_t conn,
or_handshake_state_t state,
const var_cell_t cell,
int  incoming 

Remember that a variable-length cell has been transmitted (if incoming is false) or received (if incoming is true) during a V3 handshake using state.

(We don't record the cell, but we keep a digest of everything sent or received during the v3 handshake, and the client signs it in an authenticate cell.)

Definition at line 2244 of file connection_or.c.

References crypto_digest256_new(), or_handshake_state_t::digest_sent, or_handshake_state_t::digest_sent_data, and VAR_CELL_MAX_HEADER_SIZE.


or_connection_t* TO_OR_CONN ( connection_t c)

◆ var_cell_copy()

var_cell_t* var_cell_copy ( const var_cell_t src)

Copy a var_cell_t

Definition at line 568 of file connection_or.c.

References var_cell_t::payload_len.

◆ var_cell_free_()

void var_cell_free_ ( var_cell_t cell)

Release all space held by cell.

Definition at line 587 of file connection_or.c.

References tor_free.

◆ var_cell_new()

var_cell_t* var_cell_new ( uint16_t  payload_len)

Allocate and return a new var_cell_t with payload_len bytes of payload space.

Definition at line 553 of file connection_or.c.

Referenced by connection_or_send_auth_challenge_cell(), and connection_or_send_versions().

◆ var_cell_pack_header()

int var_cell_pack_header ( const var_cell_t cell,
char *  hdr_out,
int  wide_circ_ids 

Write the header of cell into the first VAR_CELL_MAX_HEADER_SIZE bytes of hdr_out. Returns number of bytes used.

Definition at line 533 of file connection_or.c.

References var_cell_t::circ_id, set_uint16(), set_uint32(), and VAR_CELL_MAX_HEADER_SIZE.

Referenced by MOCK_IMPL().

Variable Documentation

◆ broken_connection_counts

strmap_t* broken_connection_counts

Map from a string describing what a non-open OR connection was doing when failed, to an intptr_t describing the count of connections that failed that way. Note that the count is stored as the pointer.

Definition at line 279 of file connection_or.c.

Referenced by clear_broken_connection_map(), connection_or_report_broken_states(), and note_broken_connection().

◆ disable_broken_connection_counts

int disable_broken_connection_counts = 0

If true, do not record information in broken_connection_counts.

Definition at line 282 of file connection_or.c.

Referenced by connection_or_note_state_when_broken(), connection_or_report_broken_states(), and note_broken_connection().

◆ n_or_protocol_versions

const int n_or_protocol_versions
Initial value:
(int)( sizeof(or_protocol_versions)/sizeof(uint16_t) )
static const uint16_t or_protocol_versions[]

Number of versions in or_protocol_versions.

Definition at line 2436 of file connection_or.c.

Referenced by connection_or_send_versions(), and is_or_protocol_version_known().

◆ or_protocol_versions

const uint16_t or_protocol_versions[] = { 1, 2, 3, 4, 5 }

Array of recognized link protocol versions.

Definition at line 2434 of file connection_or.c.

Referenced by is_or_protocol_version_known().

◆ orconn_ext_or_id_map

digestmap_t* orconn_ext_or_id_map = NULL

Global map between Extended ORPort identifiers and OR connections.

Definition at line 121 of file connection_or.c.

Referenced by connection_or_get_by_ext_or_id(), connection_or_remove_from_ext_or_id_map(), and connection_or_set_ext_or_identifier().