Macros | Functions | Variables
relay.c File Reference
#include "core/or/or.h"
#include "feature/client/addressmap.h"
#include "lib/err/backtrace.h"
#include "lib/buf/buffers.h"
#include "core/or/channel.h"
#include "feature/client/circpathbias.h"
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
#include "core/or/circuituse.h"
#include "core/or/circuitpadding.h"
#include "lib/compress/compress.h"
#include "app/config/config.h"
#include "core/mainloop/connection.h"
#include "core/or/connection_edge.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/dircommon/directory.h"
#include "feature/relay/dns.h"
#include "feature/stats/geoip_stats.h"
#include "feature/hs/hs_cache.h"
#include "core/mainloop/mainloop.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "core/or/onion.h"
#include "core/or/policies.h"
#include "core/or/reasons.h"
#include "core/or/relay.h"
#include "core/crypto/relay_crypto.h"
#include "feature/rend/rendcache.h"
#include "feature/rend/rendcommon.h"
#include "feature/nodelist/describe.h"
#include "feature/nodelist/routerlist.h"
#include "core/or/scheduler.h"
#include "core/or/cell_st.h"
#include "core/or/cell_queue_st.h"
#include "core/or/cpath_build_state_st.h"
#include "feature/dircommon/dir_connection_st.h"
#include "core/or/destroy_cell_queue_st.h"
#include "core/or/entry_connection_st.h"
#include "core/or/extend_info_st.h"
#include "core/or/or_circuit_st.h"
#include "core/or/origin_circuit_st.h"
#include "feature/nodelist/routerinfo_st.h"
#include "core/or/socks_request_st.h"
#include "core/or/sendme.h"

Go to the source code of this file.


#define CELL_PADDING_GAP   4


static edge_connection_trelay_lookup_conn (circuit_t *circ, cell_t *cell, cell_direction_t cell_direction, crypt_path_t *layer_hint)
static void circuit_resume_edge_reading (circuit_t *circ, crypt_path_t *layer_hint)
static int circuit_resume_edge_reading_helper (edge_connection_t *conn, circuit_t *circ, crypt_path_t *layer_hint)
static int circuit_consider_stop_edge_reading (circuit_t *circ, crypt_path_t *layer_hint)
static int circuit_queue_streams_are_blocked (circuit_t *circ)
static void adjust_exit_policy_from_exitpolicy_failure (origin_circuit_t *circ, entry_connection_t *conn, node_t *node, const tor_addr_t *addr)
static void circuit_update_channel_usage (circuit_t *circ, cell_t *cell)
int circuit_receive_relay_cell (cell_t *cell, circuit_t *circ, cell_direction_t cell_direction)
 MOCK_IMPL (int, circuit_package_relay_cell,(cell_t *cell, circuit_t *circ, cell_direction_t cell_direction, crypt_path_t *layer_hint, streamid_t on_stream, const char *filename, int lineno))
void relay_header_pack (uint8_t *dest, const relay_header_t *src)
void relay_header_unpack (relay_header_t *dest, const uint8_t *src)
static const char * relay_command_to_string (uint8_t command)
STATIC size_t get_pad_cell_offset (size_t data_len)
static void pad_cell_payload (uint8_t *cell_payload, size_t data_len)
 MOCK_IMPL (int, relay_send_command_from_edge_,(streamid_t stream_id, circuit_t *circ, uint8_t relay_command, const char *payload, size_t payload_len, crypt_path_t *cpath_layer, const char *filename, int lineno))
int connection_edge_send_command (edge_connection_t *fromconn, uint8_t relay_command, const char *payload, size_t payload_len)
static int edge_reason_is_retriable (int reason)
static int connection_ap_process_end_not_open (relay_header_t *rh, cell_t *cell, origin_circuit_t *circ, entry_connection_t *conn, crypt_path_t *layer_hint)
static void remap_event_helper (entry_connection_t *conn, const tor_addr_t *new_addr)
STATIC int connected_cell_parse (const relay_header_t *rh, const cell_t *cell, tor_addr_t *addr_out, int *ttl_out)
STATIC void address_ttl_free_ (address_ttl_t *addr)
STATIC int resolved_cell_parse (const cell_t *cell, const relay_header_t *rh, smartlist_t *addresses_out, int *errcode_out)
static void connection_ap_handshake_socks_got_resolved_cell (entry_connection_t *conn, int error_code, smartlist_t *results)
STATIC int connection_edge_process_resolved_cell (edge_connection_t *conn, const cell_t *cell, const relay_header_t *rh)
static int connection_edge_process_relay_cell_not_open (relay_header_t *rh, cell_t *cell, circuit_t *circ, edge_connection_t *conn, crypt_path_t *layer_hint)
static int process_sendme_cell (const relay_header_t *rh, const cell_t *cell, circuit_t *circ, edge_connection_t *conn, crypt_path_t *layer_hint, int domain)
STATIC int connection_edge_process_relay_cell (cell_t *cell, circuit_t *circ, edge_connection_t *conn, crypt_path_t *layer_hint)
void circuit_reset_sendme_randomness (circuit_t *circ)
STATIC size_t connection_edge_get_inbuf_bytes_to_package (size_t n_available, int package_partial, circuit_t *on_circuit)
int connection_edge_package_raw_inbuf (edge_connection_t *conn, int package_partial, int *max_cells)
static void packed_cell_free_unchecked (packed_cell_t *cell)
STATIC packed_cell_tpacked_cell_new (void)
void packed_cell_free_ (packed_cell_t *cell)
void dump_cell_pool_usage (int severity)
static packed_cell_tpacked_cell_copy (const cell_t *cell, int wide_circ_ids)
void cell_queue_append (cell_queue_t *queue, packed_cell_t *cell)
void cell_queue_append_packed_copy (circuit_t *circ, cell_queue_t *queue, int exitward, const cell_t *cell, int wide_circ_ids, int use_stats)
void cell_queue_init (cell_queue_t *queue)
void cell_queue_clear (cell_queue_t *queue)
STATIC packed_cell_tcell_queue_pop (cell_queue_t *queue)
void destroy_cell_queue_init (destroy_cell_queue_t *queue)
void destroy_cell_queue_clear (destroy_cell_queue_t *queue)
STATIC destroy_cell_tdestroy_cell_queue_pop (destroy_cell_queue_t *queue)
void destroy_cell_queue_append (destroy_cell_queue_t *queue, circid_t circid, uint8_t reason)
static packed_cell_tdestroy_cell_to_packed_cell (destroy_cell_t *inp, int wide_circ_ids)
size_t packed_cell_mem_cost (void)
size_t cell_queues_get_total_allocation (void)
STATIC int cell_queues_check_size (void)
int have_been_under_memory_pressure (void)
void update_circuit_on_cmux_ (circuit_t *circ, cell_direction_t direction, const char *file, int lineno)
void channel_unlink_all_circuits (channel_t *chan, smartlist_t *circuits_out)
static int set_streams_blocked_on_circ (circuit_t *circ, channel_t *chan, int block, streamid_t stream_id)
uint8_t packed_cell_get_command (const packed_cell_t *cell, int wide_circ_ids)
circid_t packed_cell_get_circid (const packed_cell_t *cell, int wide_circ_ids)
 MOCK_IMPL (int, channel_flush_from_first_active_circuit,(channel_t *chan, int max))
void relay_consensus_has_changed (const networkstatus_t *ns)
void append_cell_to_circuit_queue (circuit_t *circ, channel_t *chan, cell_t *cell, cell_direction_t direction, streamid_t fromstream)
int append_address_to_payload (uint8_t *payload_out, const tor_addr_t *addr)
const uint8_t * decode_address_from_payload (tor_addr_t *addr_out, const uint8_t *payload, int payload_len)
void circuit_clear_cell_queue (circuit_t *circ, channel_t *chan)


uint64_t stats_n_relay_cells_relayed = 0
uint64_t stats_n_relay_cells_delivered = 0
uint64_t stats_n_circ_max_cell_reached = 0
uint64_t stats_n_data_cells_packaged = 0
uint64_t stats_n_data_bytes_packaged = 0
uint64_t stats_n_data_cells_received = 0
uint64_t stats_n_data_bytes_received = 0
static size_t total_cells_allocated = 0
static time_t last_time_under_memory_pressure = 0
static int32_t max_circuit_cell_queue_size

Detailed Description

Handle relay cell encryption/decryption, plus packaging and receiving from circuits, plus queuing on circuits.

This is a core modules that makes Tor work. It's responsible for dealing with RELAY cells (the ones that travel more than one hop along a circuit), by:

RELAY cells are generated throughout the code at the client or relay side, using relay_send_command_from_edge() or one of the functions like connection_edge_send_command() that calls it. Of particular interest is connection_edge_package_raw_inbuf(), which takes information that has arrived on an edge connection socket, and packages it as a RELAY_DATA cell – this is how information is actually sent across the Tor network. The cryptography for these functions is handled deep in circuit_package_relay_cell(), which either adds a single layer of encryption (if we're an exit), or multiple layers (if we're the origin of the circuit). After construction and encryption, the RELAY cells are passed to append_cell_to_circuit_queue(), which queues them for transmission and tells the circuitmux (see circuitmux.c) that the circuit is waiting to send something.

Incoming RELAY cells arrive at circuit_receive_relay_cell(), called from command.c. There they are decrypted and, if they are for us, are passed to connection_edge_process_relay_cell(). If they're not for us, they're re-queued for retransmission again with append_cell_to_circuit_queue().

The connection_edge_process_relay_cell() function handles all the different types of relay cells, launching requests or transmitting data as needed.

Definition in file relay.c.

Macro Definition Documentation


#define CELL_PADDING_GAP   4

When padding a cell with randomness, leave this many zeros after the payload.

Definition at line 538 of file relay.c.



Stop reading on edge connections when we have this many cells waiting on the appropriate queue.

Definition at line 117 of file relay.c.



Start reading from edge connections again when we get down to this many cells.

Definition at line 120 of file relay.c.



How many times will I retry a stream that fails due to DNS resolve failure or misc error?

Definition at line 784 of file relay.c.



How long after we've been low on memory should we try to conserve it?

Definition at line 2669 of file relay.c.



Any relay data payload containing fewer than this many real bytes is considered to have enough randomness to.

Definition at line 2051 of file relay.c.

Function Documentation

◆ address_ttl_free_()

STATIC void address_ttl_free_ ( address_ttl_t *  addr)

Drop all storage held by addr.

Definition at line 1103 of file relay.c.

References tor_free.

◆ adjust_exit_policy_from_exitpolicy_failure()

static void adjust_exit_policy_from_exitpolicy_failure ( origin_circuit_t circ,
entry_connection_t conn,
node_t node,
const tor_addr_t addr 

Called when we have gotten an END_REASON_EXITPOLICY failure on circ for conn, while attempting to connect via node. If the node told us which address it rejected, then addr is that address; otherwise it is AF_UNSPEC.

If we are sure the node should have allowed this address, mark the node as having a reject *:* exit policy. Otherwise, mark the circuit as unusable for this particular address.

Definition at line 1010 of file relay.c.

References socks_request_t::address, entry_connection_t::chosen_exit_name, node_exit_policy_is_exact(), entry_connection_t::socks_request, tor_addr_family(), and tor_addr_parse().

◆ append_address_to_payload()

int append_address_to_payload ( uint8_t *  payload_out,
const tor_addr_t addr 

Append an encoded value of addr to payload_out, which must have at least 18 bytes of free space. The encoding is, as specified in tor-spec.txt: RESOLVED_TYPE_IPV4 or RESOLVED_TYPE_IPV6 [1 byte] LENGTH [1 byte] ADDRESS [length bytes] Return the number of bytes added, or -1 on error

Definition at line 3156 of file relay.c.

References tor_addr_family().

◆ append_cell_to_circuit_queue()

void append_cell_to_circuit_queue ( circuit_t circ,
channel_t chan,
cell_t cell,
cell_direction_t  direction,
streamid_t  fromstream 

Add cell to the queue of circ writing to chan transmitting in direction.

The given cell is copied onto the circuit queue so the caller must cleanup the memory.

This function is part of the fast path.

Definition at line 3083 of file relay.c.

References CELL_DIRECTION_OUT, circuit_t::marked_for_close, circuit_t::n_chan_cells, or_circuit_t::p_chan_cells, circuit_t::streams_blocked_on_n_chan, circuit_t::streams_blocked_on_p_chan, and TO_OR_CIRCUIT().

◆ cell_queue_append()

void cell_queue_append ( cell_queue_t queue,
packed_cell_t cell 

Append cell to the end of queue.

Definition at line 2528 of file relay.c.

References cell_queue_t::n.

Referenced by cell_queue_append_packed_copy().

◆ cell_queue_append_packed_copy()

void cell_queue_append_packed_copy ( circuit_t circ,
cell_queue_t queue,
int  exitward,
const cell_t cell,
int  wide_circ_ids,
int  use_stats 

Append a newly allocated copy of cell to the end of the exitward (or app-ward) queue of circ. If use_stats is true, record statistics about the cell.

Definition at line 2539 of file relay.c.

References cell_queue_append(), packed_cell_t::inserted_timestamp, monotime_coarse_get_stamp(), and packed_cell_copy().

◆ cell_queue_clear()

void cell_queue_clear ( cell_queue_t queue)

Remove and free every cell in queue.

Definition at line 2563 of file relay.c.

References cell_queue_t::n, and packed_cell_free_unchecked().

Referenced by circuit_clear_cell_queue().

◆ cell_queue_init()

void cell_queue_init ( cell_queue_t queue)

Initialize queue as an empty cell queue.

Definition at line 2555 of file relay.c.

Referenced by init_circuit_base().

◆ cell_queue_pop()

STATIC packed_cell_t* cell_queue_pop ( cell_queue_t queue)

Extract and return the cell at the head of queue; return NULL if queue is empty.

Definition at line 2577 of file relay.c.

References cell_queue_t::n.

◆ cell_queues_check_size()

STATIC int cell_queues_check_size ( void  )

Check whether we've got too much space used for cells. If so, call the OOM handler and return 1. Otherwise, return 0.

Definition at line 2677 of file relay.c.

◆ channel_unlink_all_circuits()

void channel_unlink_all_circuits ( channel_t chan,
smartlist_t circuits_out 

Remove all circuits from the cmux on chan.

If circuits_out is non-NULL, add all detached circuits to circuits_out.

Definition at line 2779 of file relay.c.

References circuitmux_detach_all_circuits(), channel_s::cmux, channel_s::num_n_circuits, and tor_assert().

Referenced by circuit_unlink_all_from_channel().

◆ circuit_clear_cell_queue()

void circuit_clear_cell_queue ( circuit_t circ,
channel_t chan 

◆ circuit_consider_stop_edge_reading()

static int circuit_consider_stop_edge_reading ( circuit_t circ,
crypt_path_t layer_hint 

Check if the package window for circ is empty (at hop layer_hint if it's defined).

If yes, tell edge streams to stop reading and return 1. Else return 0.

Definition at line 2438 of file relay.c.

References LD_APP.

◆ circuit_queue_streams_are_blocked()

static int circuit_queue_streams_are_blocked ( circuit_t circ)

Return 1 if we shouldn't restart reading on this circuit, even if we get a SENDME. Else return 0.

Definition at line 3237 of file relay.c.

References CIRCUIT_IS_ORIGIN, circuit_t::streams_blocked_on_n_chan, and circuit_t::streams_blocked_on_p_chan.

Referenced by circuit_resume_edge_reading().

◆ circuit_receive_relay_cell()

int circuit_receive_relay_cell ( cell_t cell,
circuit_t circ,
cell_direction_t  cell_direction 

Receive a relay cell:

  • Crypt it (encrypt if headed toward the origin or if we are the origin; decrypt if we're headed toward the exit).
  • Check if recognized (if exitward).
  • If recognized and the digest checks out, then find if there's a stream that the cell is intended for, and deliver it to the right connection_edge.
  • If not recognized, then we need to relay it: append it to the appropriate cell_queue on circ.

Return -reason on failure.

Definition at line 223 of file relay.c.

References CELL_DIRECTION_IN, CELL_DIRECTION_OUT, log_fn, circuit_t::marked_for_close, and tor_assert().

◆ circuit_reset_sendme_randomness()

void circuit_reset_sendme_randomness ( circuit_t circ)

Called when initializing a circuit, or when we have reached the end of the window in which we need to send some randomness so that incoming sendme cells will be unpredictable. Resets the flags and picks a new window.

Definition at line 2040 of file relay.c.

References CIRCWINDOW_INCREMENT, crypto_fast_rng_get_uint(), get_thread_fast_rng(), circuit_t::have_sent_sufficiently_random_cell, and circuit_t::send_randomness_after_n_cells.

Referenced by init_circuit_base().

◆ circuit_resume_edge_reading()

static void circuit_resume_edge_reading ( circuit_t circ,
crypt_path_t layer_hint 

The circuit circ has received a circuit-level sendme (on hop layer_hint, if we're the OP). Go through all the attached streams and let them resume reading and packaging, if their stream windows allow it.

Definition at line 2260 of file relay.c.

References circuit_queue_streams_are_blocked().

◆ circuit_resume_edge_reading_helper()

static int circuit_resume_edge_reading_helper ( edge_connection_t first_conn,
circuit_t circ,
crypt_path_t layer_hint 

◆ circuit_update_channel_usage()

static void circuit_update_channel_usage ( circuit_t circ,
cell_t cell 

Update channel usage state based on the type of relay cell and circuit properties.

This is needed to determine if a client channel is being used for application traffic, and if a relay channel is being used for multihop circuits and application traffic. The decision to pad in channelpadding.c depends upon this info (as well as consensus parameters) to decide what channels to pad.

Definition at line 145 of file relay.c.


◆ connected_cell_parse()

STATIC int connected_cell_parse ( const relay_header_t rh,
const cell_t cell,
tor_addr_t addr_out,
int *  ttl_out 

Extract the contents of a connected cell in cell, whose relay header has already been parsed into rh. On success, set addr_out to the address we're connected to, and ttl_out to the ttl of that address, in seconds, and return 0. On failure, return -1.

Note that the resulting address can be UNSPEC if the connected cell had no address (as for a stream to an union service or a tunneled directory connection), and that the ttl can be absent (in which case ttl_out is set to -1).

Definition at line 1065 of file relay.c.

References get_uint32(), relay_header_t::length, cell_t::payload, RELAY_HEADER_SIZE, tor_addr_from_ipv4h, and tor_addr_make_unspec().

◆ connection_ap_handshake_socks_got_resolved_cell()

static void connection_ap_handshake_socks_got_resolved_cell ( entry_connection_t conn,
int  error_code,
smartlist_t results 

Helper for connection_edge_process_resolved_cell: given an error code, an entry_connection, and a list of address_ttl_t *, report the best answer to the entry_connection.

Definition at line 1214 of file relay.c.

References tor_assert().

◆ connection_ap_process_end_not_open()

static int connection_ap_process_end_not_open ( relay_header_t rh,
cell_t cell,
origin_circuit_t circ,
entry_connection_t conn,
crypt_path_t layer_hint 

Called when we receive an END cell on a stream that isn't open yet, from the client side. Arguments are as for connection_edge_process_relay_cell().

Definition at line 804 of file relay.c.

References relay_header_t::length, cell_t::payload, and RELAY_HEADER_SIZE.

◆ connection_edge_get_inbuf_bytes_to_package()

STATIC size_t connection_edge_get_inbuf_bytes_to_package ( size_t  n_available,
int  package_partial,
circuit_t on_circuit 

Helper. Return the number of bytes that should be put into a cell from a given edge connection on which n_available bytes are available.

Definition at line 2059 of file relay.c.

References circuit_t::have_sent_sufficiently_random_cell, RELAY_PAYLOAD_LENGTH_FOR_RANDOM_SENDMES, RELAY_PAYLOAD_SIZE, and circuit_t::send_randomness_after_n_cells.

◆ connection_edge_package_raw_inbuf()

int connection_edge_package_raw_inbuf ( edge_connection_t conn,
int  package_partial,
int *  max_cells 

If conn has an entire relay payload of bytes on its inbuf (or package_partial is true), and the appropriate package windows aren't empty, grab a cell and send it down the circuit.

If *max_cells is given, package no more than max_cells. Decrement *max_cells by the number of cells packaged.

Return -1 (and send a RELAY_COMMAND_END cell if necessary) if conn should be marked for close, else return 0.

Definition at line 2123 of file relay.c.

References CELL_PAYLOAD_SIZE, CONN_TYPE_AP, LD_APP, and connection_t::type.

◆ connection_edge_process_relay_cell()

STATIC int connection_edge_process_relay_cell ( cell_t cell,
circuit_t circ,
edge_connection_t conn,
crypt_path_t layer_hint 

An incoming relay cell has arrived on circuit circ. If conn is NULL this is a control cell, else cell is destined for conn.

If layer_hint is defined, then we're the origin of the circuit, and it specifies the hop that packaged cell.

Return -reason if you want to warn and tear down the circuit, else 0.

Definition at line 1589 of file relay.c.

References LD_APP.

◆ connection_edge_process_relay_cell_not_open()

static int connection_edge_process_relay_cell_not_open ( relay_header_t rh,
cell_t cell,
circuit_t circ,
edge_connection_t conn,
crypt_path_t layer_hint 

An incoming relay cell has arrived from circuit circ to stream conn.

The arguments here are the same as in connection_edge_process_relay_cell() below; this function is called from there when conn is defined and not in an open state.

Definition at line 1363 of file relay.c.

References relay_header_t::command.

◆ connection_edge_process_resolved_cell()

STATIC int connection_edge_process_resolved_cell ( edge_connection_t conn,
const cell_t cell,
const relay_header_t rh 

Handle a RELAY_COMMAND_RESOLVED cell that we received on a non-open AP stream.

Definition at line 1288 of file relay.c.

◆ connection_edge_send_command()

int connection_edge_send_command ( edge_connection_t fromconn,
uint8_t  relay_command,
const char *  payload,
size_t  payload_len 

Make a relay cell out of relay_command and payload, and send it onto the open circuit circ. fromconn is the stream that's sending the relay cell, or NULL if it's a control cell. cpath_layer is NULL for OR->OP cells, or the destination hop for OP->OR cells.

If you can't send the cell, mark the circuit for close and return -1. Else return 0.

Definition at line 728 of file relay.c.

References edge_connection_t::cpath_layer, connection_t::marked_for_close, edge_connection_t::on_circuit, and tor_assert().

◆ decode_address_from_payload()

const uint8_t* decode_address_from_payload ( tor_addr_t addr_out,
const uint8_t *  payload,
int  payload_len 

Given payload_len bytes at payload, starting with an address encoded as by append_address_to_payload(), try to decode the address into *addr_out. Return the next byte in the payload after the address on success, or NULL on failure.

Definition at line 3182 of file relay.c.

◆ destroy_cell_queue_append()

void destroy_cell_queue_append ( destroy_cell_queue_t queue,
circid_t  circid,
uint8_t  reason 

Append a destroy cell for circid to queue.

Definition at line 2623 of file relay.c.

◆ destroy_cell_queue_clear()

void destroy_cell_queue_clear ( destroy_cell_queue_t queue)

Remove and free every cell in queue.

Definition at line 2597 of file relay.c.

References destroy_cell_queue_t::n, and tor_free.

◆ destroy_cell_queue_init()

void destroy_cell_queue_init ( destroy_cell_queue_t queue)

Initialize queue as an empty cell queue.

Definition at line 2589 of file relay.c.

◆ destroy_cell_queue_pop()

STATIC destroy_cell_t* destroy_cell_queue_pop ( destroy_cell_queue_t queue)

Extract and return the cell at the head of queue; return NULL if queue is empty.

Definition at line 2611 of file relay.c.

References destroy_cell_queue_t::n.

Referenced by MOCK_IMPL().

◆ destroy_cell_to_packed_cell()

static packed_cell_t* destroy_cell_to_packed_cell ( destroy_cell_t inp,
int  wide_circ_ids 

Convert a destroy_cell_t to a newly allocated cell_t. Frees its input.

Definition at line 2639 of file relay.c.

References cell_t::circ_id, cell_t::command, and packed_cell_new().

Referenced by MOCK_IMPL().

◆ dump_cell_pool_usage()

void dump_cell_pool_usage ( int  severity)

Log current statistics for cell pool allocation at log level severity.

Definition at line 2501 of file relay.c.

References CIRCUIT_IS_ORIGIN, cell_queue_t::n, or_circuit_t::p_chan_cells, SMARTLIST_FOREACH_BEGIN, and TO_OR_CIRCUIT().

Referenced by dumpmemusage().

◆ edge_reason_is_retriable()

static int edge_reason_is_retriable ( int  reason)

Return 1 if reason is something that you should retry if you get the end cell before you've connected; else return 0.

Definition at line 789 of file relay.c.

◆ get_pad_cell_offset()

STATIC size_t get_pad_cell_offset ( size_t  data_len)

Return the offset where the padding should start. The data_len is the relay payload length expected to be put in the cell. It can not be bigger than RELAY_PAYLOAD_SIZE else this function assert().

Value will always be smaller than CELL_PAYLOAD_SIZE because this offset is for the entire cell length not just the data payload length. Zero is returned if there is no room for padding.

This function always skips the first 4 bytes after the payload because having some unused zero bytes has saved us a lot of times in the past.

Definition at line 552 of file relay.c.


◆ have_been_under_memory_pressure()

int have_been_under_memory_pressure ( void  )

Return true if we've been under memory pressure in the last MEMORY_PRESSURE_INTERVAL seconds.

Definition at line 2723 of file relay.c.

References approx_time(), last_time_under_memory_pressure, and MEMORY_PRESSURE_INTERVAL.

◆ MOCK_IMPL() [1/3]

MOCK_IMPL ( int  ,
circuit_package_relay_cell  ,
(cell_t *cell, circuit_t *circ, cell_direction_t cell_direction, crypt_path_t *layer_hint, streamid_t on_stream, const char *filename, int lineno)   

Package a relay cell from an edge:

  • Encrypt it to the right layer
  • Append it to the appropriate cell_queue on circ.

Definition at line 356 of file relay.c.

References CELL_DIRECTION_OUT, circuit_t::marked_for_close, and circuit_t::n_chan.

◆ MOCK_IMPL() [2/3]

MOCK_IMPL ( int  ,
relay_send_command_from_edge_  ,
(streamid_t stream_id, circuit_t *circ, uint8_t relay_command, const char *payload, size_t payload_len, crypt_path_t *cpath_layer, const char *filename, int lineno)   

Make a relay cell out of relay_command and payload, and send it onto the open circuit circ. stream_id is the ID on circ for the stream that's sending the relay cell, or 0 if it's a control cell. cpath_layer is NULL for OR->OP cells, or the destination hop for OP->OR cells.

If you can't send the cell, mark the circuit for close and return -1. Else return 0.

Definition at line 603 of file relay.c.

References cell_t::command, RELAY_PAYLOAD_SIZE, and tor_assert().

◆ MOCK_IMPL() [3/3]

MOCK_IMPL ( int  ,
channel_flush_from_first_active_circuit  ,
(channel_t *chan, int max)   

Pull as many cells as possible (but no more than max) from the queue of the first active circuit on chan, and write them to chan->outbuf. Return the number of cells written. Advance the active circuit pointer to the next active circuit in the ring.

Definition at line 2869 of file relay.c.

References channel_mark_for_close(), channel_write_packed_cell(), circuitmux_get_first_active_circuit(), circuitmux_notify_xmit_destroy(), channel_s::cmux, destroy_cell_queue_pop(), destroy_cell_to_packed_cell(), destroy_cell_queue_t::n, cell_queue_t::n, circuit_t::n_chan, circuit_t::n_chan_cells, or_circuit_t::p_chan, or_circuit_t::p_chan_cells, circuit_t::streams_blocked_on_n_chan, circuit_t::streams_blocked_on_p_chan, TO_OR_CIRCUIT(), and tor_assert().

◆ packed_cell_copy()

static packed_cell_t* packed_cell_copy ( const cell_t cell,
int  wide_circ_ids 

Allocate a new copy of packed cell.

Definition at line 2519 of file relay.c.

References cell_pack(), and packed_cell_new().

Referenced by cell_queue_append_packed_copy().

◆ packed_cell_free_()

void packed_cell_free_ ( packed_cell_t cell)

Return a packed cell used outside by channel_t lower layer

Definition at line 2491 of file relay.c.

References packed_cell_free_unchecked().

◆ packed_cell_free_unchecked()

static void packed_cell_free_unchecked ( packed_cell_t cell)

Release storage held by cell.

Definition at line 2475 of file relay.c.

References tor_free, and total_cells_allocated.

Referenced by cell_queue_clear(), and packed_cell_free_().

◆ packed_cell_get_circid()

circid_t packed_cell_get_circid ( const packed_cell_t cell,
int  wide_circ_ids 

Extract the circuit ID from a packed cell.

Definition at line 2856 of file relay.c.

References packed_cell_t::body, get_uint16(), and get_uint32().

◆ packed_cell_get_command()

uint8_t packed_cell_get_command ( const packed_cell_t cell,
int  wide_circ_ids 

Extract the command from a packed cell.

Definition at line 2845 of file relay.c.

Referenced by write_packed_cell().

◆ packed_cell_mem_cost()

size_t packed_cell_mem_cost ( void  )

Return the total number of bytes used for each packed_cell in a queue. Approximate.

Definition at line 2656 of file relay.c.

◆ packed_cell_new()

STATIC packed_cell_t* packed_cell_new ( void  )

Allocate and return a new packed_cell_t.

Definition at line 2483 of file relay.c.

References total_cells_allocated.

Referenced by destroy_cell_to_packed_cell(), and packed_cell_copy().

◆ process_sendme_cell()

static int process_sendme_cell ( const relay_header_t rh,
const cell_t cell,
circuit_t circ,
edge_connection_t conn,
crypt_path_t layer_hint,
int  domain 

Process a SENDME cell that arrived on circ. If it is a stream level cell, it is destined for the given conn. If it is a circuit level cell, it is destined for the layer_hint. The domain is the logging domain that should be used.

Return 0 if everything went well or a negative value representing a circuit end reason on error for which the caller is responsible for closing it.

Definition at line 1512 of file relay.c.

References relay_header_t::stream_id, and tor_assert().

◆ relay_command_to_string()

static const char* relay_command_to_string ( uint8_t  command)

Convert the relay command into a human-readable string.

Definition at line 498 of file relay.c.

◆ relay_header_pack()

void relay_header_pack ( uint8_t *  dest,
const relay_header_t src 

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

Definition at line 474 of file relay.c.

◆ relay_header_unpack()

void relay_header_unpack ( relay_header_t dest,
const uint8_t *  src 

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

Definition at line 487 of file relay.c.

References relay_header_t::command.

Referenced by connection_exit_begin_conn(), connection_exit_begin_resolve(), pathbias_check_probe_response(), pathbias_count_valid_cells(), and relay_lookup_conn().

◆ relay_lookup_conn()

static edge_connection_t * relay_lookup_conn ( circuit_t circ,
cell_t cell,
cell_direction_t  cell_direction,
crypt_path_t layer_hint 

If cell's stream_id matches the stream_id of any conn that's attached to circ, return that conn, else return NULL.

Definition at line 421 of file relay.c.

References CIRCUIT_IS_ORIGIN, edge_connection_t::cpath_layer, connection_t::marked_for_close, edge_connection_t::next_stream, cell_t::payload, relay_header_unpack(), edge_connection_t::stream_id, relay_header_t::stream_id, and TO_ORIGIN_CIRCUIT().

◆ remap_event_helper()

static void remap_event_helper ( entry_connection_t conn,
const tor_addr_t new_addr 

Helper: change the socks_request->address field on conn to the dotted-quad representation of new_addr, and send an appropriate REMAP event.

Definition at line 1045 of file relay.c.

References socks_request_t::address, control_event_stream_status(), entry_connection_t::socks_request, and tor_addr_to_str().

◆ resolved_cell_parse()

STATIC int resolved_cell_parse ( const cell_t cell,
const relay_header_t rh,
smartlist_t addresses_out,
int *  errcode_out 

Parse a resolved cell in cell, with parsed header in rh. Return -1 on parse error. On success, add one or more newly allocated address_ttl_t to addresses_out; set *errcode_out to one of 0, RESOLVED_TYPE_ERROR, or RESOLVED_TYPE_ERROR_TRANSIENT, and return 0.

Definition at line 1117 of file relay.c.

References relay_header_t::length, cell_t::payload, RELAY_HEADER_SIZE, RELAY_PAYLOAD_SIZE, and tor_assert().

◆ set_streams_blocked_on_circ()

static int set_streams_blocked_on_circ ( circuit_t circ,
channel_t chan,
int  block,
streamid_t  stream_id 

Block (if block is true) or unblock (if block is false) every edge connection that is using circ to write to chan, and start or stop reading as appropriate.

If stream_id is nonzero, block only the edge connection whose stream_id matches it.

Returns the number of streams whose status we changed.

Definition at line 2799 of file relay.c.

References CIRCUIT_IS_ORIGIN, connection_is_reading(), edge_connection_t::edge_blocked_on_circ, circuit_t::n_chan, or_circuit_t::n_streams, edge_connection_t::next_stream, origin_circuit_t::p_streams, connection_t::read_event, edge_connection_t::stream_id, circuit_t::streams_blocked_on_n_chan, circuit_t::streams_blocked_on_p_chan, TO_CONN, TO_OR_CIRCUIT(), TO_ORIGIN_CIRCUIT(), and tor_assert().

◆ update_circuit_on_cmux_()

void update_circuit_on_cmux_ ( circuit_t circ,
cell_direction_t  direction,
const char *  file,
int  lineno 

Update the number of cells available on the circuit's n_chan or p_chan's circuit mux.

Definition at line 2734 of file relay.c.

References CELL_DIRECTION_OUT, circuitmux_is_circuit_attached(), channel_s::cmux, circuit_t::n_chan, or_circuit_t::p_chan, TO_OR_CIRCUIT(), and tor_assert().

Variable Documentation

◆ last_time_under_memory_pressure

time_t last_time_under_memory_pressure = 0

The time at which we were last low on memory.

Definition at line 2672 of file relay.c.

Referenced by have_been_under_memory_pressure().

◆ max_circuit_cell_queue_size

int32_t max_circuit_cell_queue_size
Initial value:

Definition at line 3056 of file relay.c.

◆ stats_n_circ_max_cell_reached

uint64_t stats_n_circ_max_cell_reached = 0

Stats: how many circuits have we closed due to the cell queue limit being reached (see append_cell_to_circuit_queue())

Definition at line 132 of file relay.c.

◆ stats_n_data_bytes_packaged

uint64_t stats_n_data_bytes_packaged = 0

How many bytes of data have we put in relay_data cells have we built, ever? This would be RELAY_PAYLOAD_SIZE*stats_n_data_cells_packaged if every relay cell we ever sent were completely full of data.

Definition at line 2026 of file relay.c.

◆ stats_n_data_bytes_received

uint64_t stats_n_data_bytes_received = 0

How many bytes of data have we received relay_data cells, ever? This would be RELAY_PAYLOAD_SIZE*stats_n_data_cells_packaged if every relay cell we ever received were completely full of data.

Definition at line 2032 of file relay.c.

◆ stats_n_data_cells_packaged

uint64_t stats_n_data_cells_packaged = 0

How many relay_data cells have we built, ever?

Definition at line 2022 of file relay.c.

◆ stats_n_data_cells_received

uint64_t stats_n_data_cells_received = 0

How many relay_data cells have we received, ever?

Definition at line 2028 of file relay.c.

◆ stats_n_relay_cells_delivered

uint64_t stats_n_relay_cells_delivered = 0

Stats: how many relay cells have been delivered to streams at this hop?

Definition at line 129 of file relay.c.

◆ stats_n_relay_cells_relayed

uint64_t stats_n_relay_cells_relayed = 0

Stats: how many relay cells have originated at this hop, or have been relayed onward (not recognized at this hop)?

Definition at line 125 of file relay.c.

◆ total_cells_allocated

size_t total_cells_allocated = 0

The total number of cells we have allocated.

Definition at line 2471 of file relay.c.

Referenced by packed_cell_free_unchecked(), and packed_cell_new().