relay.c File Reference

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

#include <math.h>
#include "or.h"
#include "mempool.h"

Defines

#define MAX_RESOLVE_FAILURES   3
#define CELL_QUEUE_HIGHWATER_SIZE   256
#define CELL_QUEUE_LOWWATER_SIZE   64
#define assert_active_circuits_ok_paranoid(conn)
#define SECONDS_IN_A_DAY   86400L
#define EWMA_TICK_LEN   10
#define EWMA_DEFAULT_HALFLIFE   0.0
#define EPSILON   0.00001
#define LOG_ONEHALF   -0.69314718055994529

Functions

static int relay_crypt (circuit_t *circ, cell_t *cell, cell_direction_t cell_direction, crypt_path_t **layer_hint, char *recognized)
static edge_connection_trelay_lookup_conn (circuit_t *circ, cell_t *cell, cell_direction_t cell_direction, crypt_path_t *layer_hint)
static int connection_edge_process_relay_cell (cell_t *cell, circuit_t *circ, edge_connection_t *conn, crypt_path_t *layer_hint)
static void circuit_consider_sending_sendme (circuit_t *circ, 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 void tor_gettimeofday_cached (struct timeval *tv)
void tor_gettimeofday_cache_clear (void)
static void relay_set_digest (crypto_digest_env_t *digest, cell_t *cell)
static int relay_digest_matches (crypto_digest_env_t *digest, cell_t *cell)
static int relay_crypt_one_payload (crypto_cipher_env_t *cipher, char *in, int encrypt_mode)
int circuit_receive_relay_cell (cell_t *cell, circuit_t *circ, cell_direction_t cell_direction)
static int circuit_package_relay_cell (cell_t *cell, circuit_t *circ, cell_direction_t cell_direction, crypt_path_t *layer_hint)
void relay_header_pack (char *dest, const relay_header_t *src)
void relay_header_unpack (relay_header_t *dest, const char *src)
static const char * relay_command_to_string (uint8_t command)
int relay_send_command_from_edge (uint16_t stream_id, circuit_t *circ, uint8_t relay_command, const char *payload, size_t payload_len, crypt_path_t *cpath_layer)
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, edge_connection_t *conn, crypt_path_t *layer_hint)
static void remap_event_helper (edge_connection_t *conn, uint32_t new_addr)
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)
int connection_edge_package_raw_inbuf (edge_connection_t *conn, int package_partial)
void connection_edge_consider_sending_sendme (edge_connection_t *conn)
void init_cell_pool (void)
void free_cell_pool (void)
void clean_cell_pool (void)
static INLINE void packed_cell_free_unchecked (packed_cell_t *cell)
static INLINE packed_cell_tpacked_cell_alloc (void)
void dump_cell_pool_usage (int severity)
static INLINE packed_cell_tpacked_cell_copy (const cell_t *cell)
void cell_queue_append (cell_queue_t *queue, packed_cell_t *cell)
void cell_queue_append_packed_copy (cell_queue_t *queue, const cell_t *cell)
void cell_queue_clear (cell_queue_t *queue)
static INLINE packed_cell_tcell_queue_pop (cell_queue_t *queue)
static INLINE circuit_t ** next_circ_on_conn_p (circuit_t *circ, or_connection_t *conn)
static INLINE circuit_t ** prev_circ_on_conn_p (circuit_t *circ, or_connection_t *conn)
static int compare_cell_ewma_counts (const void *p1, const void *p2)
static circuit_tcell_ewma_to_circuit (cell_ewma_t *ewma)
static unsigned cell_ewma_tick_from_timeval (const struct timeval *now, double *remainder_out)
unsigned cell_ewma_get_tick (void)
void cell_ewma_set_scale_factor (or_options_t *options, networkstatus_t *consensus)
static INLINE double get_scale_factor (unsigned from_tick, unsigned to_tick)
static void scale_single_cell_ewma (cell_ewma_t *ewma, unsigned cur_tick)
static void scale_active_circuits (or_connection_t *conn, unsigned cur_tick)
static void add_cell_ewma_to_conn (or_connection_t *conn, cell_ewma_t *ewma)
static void remove_cell_ewma_from_conn (or_connection_t *conn, cell_ewma_t *ewma)
static cell_ewma_tpop_first_cell_ewma_from_conn (or_connection_t *conn)
void make_circuit_active_on_conn (circuit_t *circ, or_connection_t *conn)
void make_circuit_inactive_on_conn (circuit_t *circ, or_connection_t *conn)
void connection_or_unlink_all_active_circs (or_connection_t *orconn)
static void set_streams_blocked_on_circ (circuit_t *circ, or_connection_t *orconn, int block)
int connection_or_flush_from_first_active_circuit (or_connection_t *conn, int max, time_t now)
void append_cell_to_circuit_queue (circuit_t *circ, or_connection_t *orconn, cell_t *cell, cell_direction_t direction)
int append_address_to_payload (char *payload_out, const tor_addr_t *addr)
const char * decode_address_from_payload (tor_addr_t *addr_out, const char *payload, int payload_len)
void assert_active_circuits_ok (or_connection_t *orconn)

Variables

static struct timeval cached_time_hires = {0, 0}
uint64_t stats_n_relay_cells_relayed = 0
uint64_t stats_n_relay_cells_delivered = 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 int total_cells_allocated = 0
static mp_pool_tcell_pool = NULL
static mp_pool_tit_pool = NULL
static double ewma_scale_factor = 0.1
static int ewma_enabled = 0


Detailed Description

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


Define Documentation

#define CELL_QUEUE_HIGHWATER_SIZE   256

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

Referenced by append_cell_to_circuit_queue().

#define CELL_QUEUE_LOWWATER_SIZE   64

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

Referenced by connection_or_flush_from_first_active_circuit().

#define EWMA_DEFAULT_HALFLIFE   0.0

The default per-tick scale factor, if it hasn't been overridden by a consensus or a configuration setting. zero means "disabled".

Referenced by cell_ewma_set_scale_factor().

#define EWMA_TICK_LEN   10

How long does a tick last (seconds)?

Referenced by cell_ewma_get_tick(), cell_ewma_set_scale_factor(), and cell_ewma_tick_from_timeval().

#define MAX_RESOLVE_FAILURES   3

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

Referenced by connection_ap_process_end_not_open().


Function Documentation

static void add_cell_ewma_to_conn ( or_connection_t conn,
cell_ewma_t ewma 
) [static]

int append_address_to_payload ( char *  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

References tor_addr_family(), and tor_addr_to_ipv4n().

Referenced by connection_or_send_netinfo().

void append_cell_to_circuit_queue ( circuit_t circ,
or_connection_t orconn,
cell_t cell,
cell_direction_t  direction 
)

void assert_active_circuits_ok ( or_connection_t orconn  ) 

unsigned cell_ewma_get_tick ( void   ) 

Compute and return the current cell_ewma tick.

References approx_time(), and EWMA_TICK_LEN.

Referenced by init_circuit_base(), or_circuit_new(), and or_connection_new().

void cell_ewma_set_scale_factor ( or_options_t options,
networkstatus_t consensus 
)

Adjust the global cell scale factor based on options

References or_options_t::CircuitPriorityHalflife, EWMA_DEFAULT_HALFLIFE, EWMA_TICK_LEN, LD_OR, and networkstatus_get_param().

Referenced by networkstatus_set_current_consensus(), and options_act().

static unsigned cell_ewma_tick_from_timeval ( const struct timeval *  now,
double *  remainder_out 
) [static]

Given a timeval now, compute the cell_ewma tick in which it occurs and the fraction of the tick that has elapsed between the start of the tick and now. Return the former and store the latter in *remainder_out.

These tick values are not meant to be shared between Tor instances, or used for other purposes.

References EWMA_TICK_LEN.

Referenced by connection_or_flush_from_first_active_circuit().

static circuit_t* cell_ewma_to_circuit ( cell_ewma_t ewma  )  [static]

Given a cell_ewma_t, return a pointer to the circuit containing it.

References cell_ewma_t::is_for_p_conn, SUBTYPE_P, and TO_CIRCUIT.

Referenced by connection_or_flush_from_first_active_circuit().

void cell_queue_append ( cell_queue_t queue,
packed_cell_t cell 
)

Append cell to the end of queue.

References cell_queue_t::head, cell_queue_t::n, packed_cell_t::next, cell_queue_t::tail, and tor_assert.

Referenced by cell_queue_append_packed_copy().

void cell_queue_append_packed_copy ( cell_queue_t queue,
const cell_t cell 
)

void cell_queue_clear ( cell_queue_t queue  ) 

static INLINE packed_cell_t* cell_queue_pop ( cell_queue_t queue  )  [static]

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

References cell_queue_t::head, cell_queue_t::n, packed_cell_t::next, cell_queue_t::tail, and tor_assert.

Referenced by connection_or_flush_from_first_active_circuit().

static void circuit_consider_sending_sendme ( circuit_t circ,
crypt_path_t layer_hint 
) [static]

Check if the deliver_window for circuit circ (at hop layer_hint if it's defined) is low enough that we should send a circuit-level sendme back down the circuit. If so, send enough sendmes that the window would be overfull if we sent any more.

References CIRCWINDOW_INCREMENT, CIRCWINDOW_START, circuit_t::deliver_window, crypt_path_t::deliver_window, LD_CIRC, and relay_send_command_from_edge().

Referenced by connection_edge_process_relay_cell().

static int circuit_consider_stop_edge_reading ( circuit_t circ,
crypt_path_t layer_hint 
) [static]

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.

References connection_stop_reading(), edge_connection_t::cpath_layer, LD_APP, or_circuit_t::n_streams, edge_connection_t::next_stream, crypt_path_t::package_window, circuit_t::package_window, TO_CONN, TO_OR_CIRCUIT(), and TO_ORIGIN_CIRCUIT().

Referenced by circuit_resume_edge_reading_helper(), and connection_edge_package_raw_inbuf().

static int circuit_package_relay_cell ( cell_t cell,
circuit_t circ,
cell_direction_t  cell_direction,
crypt_path_t layer_hint 
) [static]

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.

References or_circuit_t::_base, append_cell_to_circuit_queue(), CELL_DIRECTION_IN, CELL_DIRECTION_OUT, cell_t::circ_id, CIRCUIT_IS_ORIGIN, CIRCUIT_PURPOSE_REND_ESTABLISHED, circuit_receive_relay_cell(), cell_t::command, connection_edge_process_relay_cell(), LD_BUG, LD_OR, LD_PROTOCOL, LD_REND, circuit_t::marked_for_close, circuit_t::n_circ_id, circuit_t::n_conn, or_circuit_t::p_circ_id, or_circuit_t::p_conn, circuit_t::purpose, relay_crypt(), relay_lookup_conn(), or_circuit_t::rend_splice, TO_CIRCUIT, TO_OR_CIRCUIT(), and tor_assert.

Referenced by circuit_receive_relay_cell(), and command_process_relay_cell().

static void circuit_resume_edge_reading ( circuit_t circ,
crypt_path_t layer_hint 
) [static]

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.

References CIRCUIT_IS_ORIGIN, circuit_resume_edge_reading_helper(), LD_APP, TO_OR_CIRCUIT(), and TO_ORIGIN_CIRCUIT().

Referenced by connection_edge_process_relay_cell().

static int circuit_resume_edge_reading_helper ( edge_connection_t conn,
circuit_t circ,
crypt_path_t layer_hint 
) [static]

void clean_cell_pool ( void   ) 

Free excess storage in cell pool.

References tor_assert.

Referenced by run_scheduled_events().

static int compare_cell_ewma_counts ( const void *  p1,
const void *  p2 
) [static]

Helper for sorting cell_ewma_t values in their priority queue.

References cell_ewma_t::cell_count.

Referenced by add_cell_ewma_to_conn(), pop_first_cell_ewma_from_conn(), and remove_cell_ewma_from_conn().

static int connection_ap_process_end_not_open ( relay_header_t rh,
cell_t cell,
origin_circuit_t circ,
edge_connection_t conn,
crypt_path_t layer_hint 
) [static]

void connection_edge_consider_sending_sendme ( edge_connection_t conn  ) 

Called when we've just received a relay data cell, or when we've just finished flushing all bytes to stream conn.

If conn->outbuf is not too full, and our deliver window is low, send back a suitable number of stream-level sendme cells.

References edge_connection_t::_base, circuit_get_by_edge_conn(), connection_edge_send_command(), connection_outbuf_too_full(), edge_connection_t::cpath_layer, edge_connection_t::deliver_window, LD_APP, connection_t::outbuf_flushlen, STREAMWINDOW_INCREMENT, STREAMWINDOW_START, and TO_CONN.

Referenced by connection_edge_finished_flushing(), and connection_edge_process_relay_cell().

int connection_edge_package_raw_inbuf ( edge_connection_t conn,
int  package_partial 
)

static int connection_edge_process_relay_cell ( cell_t cell,
circuit_t circ,
edge_connection_t conn,
crypt_path_t layer_hint 
) [static]

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.

References edge_connection_t::_base, circuit_consider_sending_sendme(), circuit_extend(), circuit_finish_handshake(), CIRCUIT_PURPOSE_OR, CIRCUIT_PURPOSE_S_REND_JOINED, circuit_resume_edge_reading(), circuit_send_next_onion_skin(), circuit_set_n_circid_orconn(), circuit_truncated(), CIRCWINDOW_INCREMENT, relay_header_t::command, connection_edge_consider_sending_sendme(), connection_edge_end(), connection_edge_package_raw_inbuf(), connection_edge_process_relay_cell_not_open(), connection_exit_begin_conn(), connection_exit_begin_resolve(), connection_or_send_destroy(), connection_start_reading(), connection_state_is_open(), edge_connection_t::deliver_window, circuit_t::deliver_window, crypt_path_t::deliver_window, circuit_t::dirreq_id, edge_connection_t::edge_has_sent_end, edge_connection_t::end_reason, END_STREAM_REASON_FLAG_REMOTE, socks_request_t::has_finished, connection_t::hold_open_until_flushed, LD_APP, LD_BUG, LD_PROTOCOL, relay_header_t::length, connection_t::marked_for_close, circuit_t::n_circ_id, circuit_t::n_conn, edge_connection_t::package_window, circuit_t::package_window, crypt_path_t::package_window, cell_t::payload, circuit_t::purpose, RELAY_HEADER_SIZE, relay_header_unpack(), RELAY_PAYLOAD_SIZE, relay_send_command_from_edge(), rend_process_relay_cell(), connection_t::s, edge_connection_t::socks_request, stats_n_data_bytes_received, stats_n_data_cells_received, stream_end_reason_to_string(), edge_connection_t::stream_id, relay_header_t::stream_id, STREAMWINDOW_INCREMENT, TO_CONN, TO_OR_CIRCUIT(), TO_ORIGIN_CIRCUIT(), and tor_assert.

Referenced by circuit_receive_relay_cell().

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]

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.

References edge_connection_t::_base, socks_request_t::address, AP_CONN_STATE_CONNECT_WAIT, AP_CONN_STATE_OPEN, AP_CONN_STATE_RESOLVE_WAIT, edge_connection_t::chosen_exit_name, CIRCUIT_IS_ORIGIN, circuit_log_path(), client_dns_set_addressmap(), socks_request_t::command, relay_header_t::command, conn_state_to_string(), CONN_TYPE_AP, CONN_TYPE_DIR, connection_ap_handshake_socks_reply(), connection_ap_handshake_socks_resolved(), connection_ap_process_end_not_open(), connection_edge_end(), connection_edge_package_raw_inbuf(), consensus_is_waiting_for_certs(), control_event_bootstrap(), count_loading_descriptors_progress(), DIR_PURPOSE_FETCH_CERTIFICATE, DIR_PURPOSE_FETCH_CONSENSUS, DIR_PURPOSE_FETCH_SERVERDESC, edge_connection_t::edge_has_sent_end, edge_connection_t::end_reason, END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED, END_STREAM_REASON_FLAG_REMOTE, get_options(), get_uint32(), socks_request_t::has_finished, INET_NTOA_BUF_LEN, is_internal_IP(), LD_APP, LD_PROTOCOL, relay_header_t::length, cell_t::payload, connection_t::purpose, RELAY_HEADER_SIZE, remap_event_helper(), edge_connection_t::socks_request, connection_t::state, connection_t::timestamp_lastread, TO_CONN, TO_ORIGIN_CIRCUIT(), tor_assert, tor_inet_ntoa(), and connection_t::type.

Referenced by connection_edge_process_relay_cell().

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

int connection_or_flush_from_first_active_circuit ( or_connection_t conn,
int  max,
time_t  now 
)

void connection_or_unlink_all_active_circs ( or_connection_t orconn  ) 

Remove all circuits from the list of circuits with pending cells on conn.

References or_connection_t::active_circuit_pqueue, or_connection_t::active_circuits, next_circ_on_conn_p(), prev_circ_on_conn_p(), and smartlist_clear().

Referenced by circuit_unlink_all_from_or_conn().

const char* decode_address_from_payload ( tor_addr_t addr_out,
const char *  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.

References get_uint32(), tor_addr_from_ipv4n(), tor_addr_from_ipv6_bytes(), and tor_addr_make_unspec().

Referenced by command_process_netinfo_cell().

void dump_cell_pool_usage ( int  severity  ) 

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

References _circuit_get_global_list(), CIRCUIT_IS_ORIGIN, LD_MM, cell_queue_t::n, circuit_t::n_conn_cells, circuit_t::next, or_circuit_t::p_conn_cells, and TO_OR_CIRCUIT().

Referenced by dumpmemusage().

static int edge_reason_is_retriable ( int  reason  )  [static]

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

Referenced by connection_ap_process_end_not_open().

void free_cell_pool ( void   ) 

Free all storage used to hold cells (and insertion times if we measure cell statistics).

Referenced by tor_free_all().

static INLINE double get_scale_factor ( unsigned  from_tick,
unsigned  to_tick 
) [static]

Return the multiplier necessary to convert the value of a cell sent in 'from_tick' to one sent in 'to_tick'.

Referenced by scale_active_circuits(), and scale_single_cell_ewma().

void init_cell_pool ( void   ) 

Allocate structures to hold cells.

References tor_assert.

Referenced by do_main_loop().

void make_circuit_active_on_conn ( circuit_t circ,
or_connection_t conn 
)

void make_circuit_inactive_on_conn ( circuit_t circ,
or_connection_t conn 
)

static INLINE circuit_t** next_circ_on_conn_p ( circuit_t circ,
or_connection_t conn 
) [static]

static INLINE packed_cell_t* packed_cell_alloc ( void   )  [static]

Allocate and return a new packed_cell_t.

Referenced by packed_cell_copy().

static INLINE packed_cell_t* packed_cell_copy ( const cell_t cell  )  [static]

Allocate a new copy of packed cell.

References cell_pack(), packed_cell_t::next, and packed_cell_alloc().

Referenced by cell_queue_append_packed_copy().

static INLINE void packed_cell_free_unchecked ( packed_cell_t cell  )  [static]

Release storage held by cell.

Referenced by cell_queue_clear(), and connection_or_flush_from_first_active_circuit().

static cell_ewma_t* pop_first_cell_ewma_from_conn ( or_connection_t conn  )  [static]

Remove and return the first cell_ewma_t from conn's priority queue of active circuits. Requires that the priority queue is nonempty.

References or_connection_t::active_circuit_pqueue, compare_cell_ewma_counts(), smartlist_pqueue_pop(), and STRUCT_OFFSET.

Referenced by connection_or_flush_from_first_active_circuit().

static INLINE circuit_t** prev_circ_on_conn_p ( circuit_t circ,
or_connection_t conn 
) [static]

Return a pointer to the "prev_active_on_{n,p}_conn" pointer of circ, depending on whether conn matches n_conn or p_conn.

References circuit_t::n_conn, or_circuit_t::p_conn, circuit_t::prev_active_on_n_conn, or_circuit_t::prev_active_on_p_conn, TO_OR_CIRCUIT(), and tor_assert.

Referenced by assert_active_circuits_ok(), connection_or_unlink_all_active_circs(), make_circuit_active_on_conn(), and make_circuit_inactive_on_conn().

static const char* relay_command_to_string ( uint8_t  command  )  [static]

Convert the relay command into a human-readable string.

Referenced by relay_send_command_from_edge().

static int relay_crypt ( circuit_t circ,
cell_t cell,
cell_direction_t  cell_direction,
crypt_path_t **  layer_hint,
char *  recognized 
) [static]

Do the appropriate en/decryptions for cell arriving on circ in direction cell_direction.

If cell_direction == CELL_DIRECTION_IN:

  • If we're at the origin (we're the OP), for hops 1..N, decrypt cell. If recognized, stop.
  • Else (we're not the OP), encrypt one hop. Cell is not recognized.

If cell_direction == CELL_DIRECTION_OUT:

  • decrypt one hop. Check if recognized.

If cell is recognized, set *recognized to 1, and set *layer_hint to the hop that recognized it.

Return -1 to indicate that we should mark the circuit for close, else return 0.

References crypt_path_t::b_crypto, crypt_path_t::b_digest, CELL_DIRECTION_IN, CELL_DIRECTION_OUT, CIRCUIT_IS_ORIGIN, origin_circuit_t::cpath, LD_OR, LD_PROTOCOL, crypt_path_t::next, cell_t::payload, relay_header_t::recognized, relay_crypt_one_payload(), relay_digest_matches(), relay_header_unpack(), crypt_path_t::state, TO_OR_CIRCUIT(), TO_ORIGIN_CIRCUIT(), and tor_assert.

Referenced by circuit_receive_relay_cell().

static int relay_crypt_one_payload ( crypto_cipher_env_t cipher,
char *  in,
int  encrypt_mode 
) [static]

Apply cipher to CELL_PAYLOAD_SIZE bytes of in (in place).

If encrypt_mode is 1 then encrypt, else decrypt.

Return -1 if the crypto fails, else return 0.

References CELL_PAYLOAD_SIZE, crypto_cipher_crypt_inplace(), and LD_BUG.

Referenced by circuit_package_relay_cell(), and relay_crypt().

static int relay_digest_matches ( crypto_digest_env_t digest,
cell_t cell 
) [static]

Does the digest for this circuit indicate that this cell is for us?

Update digest from the payload of cell (with the integrity part set to 0). If the integrity part is valid, return 1, else restore digest and cell to their original state and return 0.

References CELL_PAYLOAD_SIZE, crypto_digest_add_bytes(), crypto_digest_assign(), crypto_digest_dup(), crypto_digest_get_digest(), crypto_free_digest_env(), relay_header_t::integrity, cell_t::payload, relay_header_pack(), and relay_header_unpack().

Referenced by relay_crypt().

void relay_header_pack ( char *  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.

References relay_header_t::command, relay_header_t::integrity, relay_header_t::length, relay_header_t::recognized, set_uint16(), and relay_header_t::stream_id.

Referenced by relay_digest_matches(), relay_send_command_from_edge(), and relay_set_digest().

void relay_header_unpack ( relay_header_t dest,
const char *  src 
)

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

int relay_send_command_from_edge ( uint16_t  stream_id,
circuit_t circ,
uint8_t  relay_command,
const char *  payload,
size_t  payload_len,
crypt_path_t cpath_layer 
)

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.

References approx_time(), CELL_DIRECTION_IN, CELL_DIRECTION_OUT, cell_t::circ_id, CIRCUIT_IS_ORIGIN, circuit_package_relay_cell(), CIRCUIT_PURPOSE_IS_ESTABLISHED_REND, or_connection_t::client_used, relay_header_t::command, cell_t::command, origin_circuit_t::cpath, DIRREQ_END_CELL_SENT, circuit_t::dirreq_id, geoip_change_dirreq_state(), LD_BUG, LD_OR, relay_header_t::length, circuit_t::n_circ_id, circuit_t::n_conn, or_circuit_t::p_circ_id, cell_t::payload, circuit_t::purpose, relay_command_to_string(), origin_circuit_t::relay_early_cells_sent, origin_circuit_t::relay_early_commands, relay_header_pack(), RELAY_HEADER_SIZE, RELAY_PAYLOAD_SIZE, origin_circuit_t::remaining_relay_early_cells, smartlist_add(), smartlist_create(), smartlist_free(), smartlist_join_strings(), relay_header_t::stream_id, TO_OR_CIRCUIT(), TO_ORIGIN_CIRCUIT(), tor_assert, and tor_free.

Referenced by circuit_consider_sending_sendme(), circuit_send_next_onion_skin(), command_process_created_cell(), command_process_destroy_cell(), connection_edge_process_relay_cell(), connection_edge_send_command(), relay_send_end_cell_from_edge(), rend_client_send_establish_rendezvous(), rend_mid_establish_intro(), rend_mid_establish_rendezvous(), rend_mid_introduce(), rend_mid_rendezvous(), rend_service_intro_has_opened(), rend_service_rendezvous_has_opened(), and router_perform_bandwidth_test().

static void relay_set_digest ( crypto_digest_env_t digest,
cell_t cell 
) [static]

static void remap_event_helper ( edge_connection_t conn,
uint32_t  new_addr 
) [static]

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

References socks_request_t::address, control_event_stream_status(), REMAP_STREAM_SOURCE_EXIT, edge_connection_t::socks_request, and tor_inet_ntoa().

Referenced by connection_edge_process_relay_cell_not_open().

static void remove_cell_ewma_from_conn ( or_connection_t conn,
cell_ewma_t ewma 
) [static]

static void scale_active_circuits ( or_connection_t conn,
unsigned  cur_tick 
) [static]

Adjust the cell count of every active circuit on conn so that they are scaled with respect to cur_tick

Ordinarily it isn't okay to change the value of an element in a heap, but it's okay here, since we are preserving the order.

References or_connection_t::active_circuit_pqueue, or_connection_t::active_circuit_pqueue_last_recalibrated, get_scale_factor(), and tor_assert.

Referenced by connection_or_flush_from_first_active_circuit().

static void scale_single_cell_ewma ( cell_ewma_t ewma,
unsigned  cur_tick 
) [static]

Adjust the cell count of ewma so that it is scaled with respect to cur_tick

References cell_ewma_t::cell_count, get_scale_factor(), and cell_ewma_t::last_adjusted_tick.

Referenced by add_cell_ewma_to_conn().

static void set_streams_blocked_on_circ ( circuit_t circ,
or_connection_t orconn,
int  block 
) [static]


Variable Documentation

struct timeval cached_time_hires = {0, 0} [static]

Cache the current hi-res time; the cache gets reset when libevent calls us.

mp_pool_t* cell_pool = NULL [static]

A memory pool to allocate packed_cell_t objects.

double ewma_scale_factor = 0.1 [static]

The per-tick scale factor to be used when computing cell-count EWMA values. (A cell sent N ticks before the start of the current tick has value ewma_scale_factor ** N.)

Referenced by connection_or_flush_from_first_active_circuit().

mp_pool_t* it_pool = NULL [static]

Memory pool to allocate insertion_time_elem_t objects used for cell statistics.

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.

Referenced by dumpstats().

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.

Referenced by connection_edge_process_relay_cell(), and dumpstats().

How many relay_data cells have we built, ever?

Referenced by dumpstats().

How many relay_data cells have we received, ever?

Referenced by connection_edge_process_relay_cell(), and dumpstats().

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

Referenced by dumpstats().

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

Referenced by dumpstats().

int total_cells_allocated = 0 [static]

The total number of cells we have allocated from the memory pool.


Generated on Tue May 25 00:30:47 2010 for tor by  doxygen 1.5.6