Tor  0.4.7.0-alpha-dev
Macros | Functions | Variables
connection_edge.c File Reference

Handle edge streams. More...

#include "core/or/or.h"
#include "lib/err/backtrace.h"
#include "app/config/config.h"
#include "core/mainloop/connection.h"
#include "core/mainloop/mainloop.h"
#include "core/mainloop/netstatus.h"
#include "core/or/channel.h"
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
#include "core/or/circuituse.h"
#include "core/or/circuitpadding.h"
#include "core/or/connection_edge.h"
#include "core/or/connection_or.h"
#include "core/or/extendinfo.h"
#include "core/or/policies.h"
#include "core/or/reasons.h"
#include "core/or/relay.h"
#include "core/or/sendme.h"
#include "core/proto/proto_http.h"
#include "core/proto/proto_socks.h"
#include "feature/client/addressmap.h"
#include "feature/client/circpathbias.h"
#include "feature/client/dnsserv.h"
#include "feature/control/control_events.h"
#include "feature/dircache/dirserv.h"
#include "feature/dircommon/directory.h"
#include "feature/hibernate/hibernate.h"
#include "feature/hs/hs_cache.h"
#include "feature/hs/hs_circuit.h"
#include "feature/hs/hs_client.h"
#include "feature/hs/hs_common.h"
#include "feature/nodelist/describe.h"
#include "feature/nodelist/networkstatus.h"
#include "feature/nodelist/nodelist.h"
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/routerset.h"
#include "feature/relay/dns.h"
#include "feature/relay/router.h"
#include "feature/relay/routermode.h"
#include "feature/rend/rendcommon.h"
#include "feature/stats/predict_ports.h"
#include "feature/stats/rephist.h"
#include "lib/buf/buffers.h"
#include "lib/crypt_ops/crypto_util.h"
#include "core/or/cell_st.h"
#include "core/or/cpath_build_state_st.h"
#include "feature/dircommon/dir_connection_st.h"
#include "core/or/entry_connection_st.h"
#include "core/or/extend_info_st.h"
#include "feature/nodelist/node_st.h"
#include "core/or/or_circuit_st.h"
#include "core/or/origin_circuit_st.h"
#include "core/or/half_edge_st.h"
#include "core/or/socks_request_st.h"
#include "lib/evloop/compat_libevent.h"

Go to the source code of this file.

Macros

#define CONNECTION_EDGE_PRIVATE
 
#define SOCKS4_GRANTED   90
 
#define SOCKS4_REJECT   91
 
#define WARN_FAILED_HS_CONNECTION   300
 
#define MAX_CONNECTED_CELL_PAYLOAD_LEN   25
 
#define UNMARK()   do { } while (0)
 
#define REND_SERVICE_ID_LEN_BASE32   16
 
#define TRACKHOSTEXITS_RETRIES   5
 
#define WARN_INTRVL_LOOP   300
 
#define WARN_INTRVL_PRIV   300
 

Functions

static int connection_ap_handshake_process_socks (entry_connection_t *conn)
 
static int connection_ap_process_natd (entry_connection_t *conn)
 
static int connection_exit_connect_dir (edge_connection_t *exitconn)
 
static int consider_plaintext_ports (entry_connection_t *conn, uint16_t port)
 
static int connection_ap_supports_optimistic_data (const entry_connection_t *)
 
static bool network_reentry_is_allowed (void)
 
edge_connection_tTO_EDGE_CONN (connection_t *c)
 
const edge_connection_tCONST_TO_EDGE_CONN (const connection_t *c)
 
entry_connection_tTO_ENTRY_CONN (connection_t *c)
 
const entry_connection_tCONST_TO_ENTRY_CONN (const connection_t *c)
 
entry_connection_tEDGE_TO_ENTRY_CONN (edge_connection_t *c)
 
const entry_connection_tCONST_EDGE_TO_ENTRY_CONN (const edge_connection_t *c)
 
void connection_mark_unattached_ap_ (entry_connection_t *conn, int endreason, int line, const char *file)
 
int connection_edge_reached_eof (edge_connection_t *conn)
 
int connection_edge_process_inbuf (edge_connection_t *conn, int package_partial)
 
int connection_edge_destroy (circid_t circ_id, edge_connection_t *conn)
 
static int relay_send_end_cell_from_edge (streamid_t stream_id, circuit_t *circ, uint8_t reason, crypt_path_t *cpath_layer)
 
static void warn_if_hs_unreachable (const edge_connection_t *conn, uint8_t reason)
 
uint32_t clip_dns_ttl (uint32_t ttl)
 
int connection_edge_end (edge_connection_t *conn, uint8_t reason)
 
static int connection_half_edge_compare_bsearch (const void *key, const void **member)
 
STATIC void connection_half_edge_add (const edge_connection_t *conn, origin_circuit_t *circ)
 
void half_edge_free_ (half_edge_t *he)
 
size_t half_streams_get_total_allocation (void)
 
STATIC half_edge_tconnection_half_edge_find_stream_id (const smartlist_t *half_conns, streamid_t stream_id)
 
int connection_half_edge_is_valid_data (const smartlist_t *half_conns, streamid_t stream_id)
 
int connection_half_edge_is_valid_connected (const smartlist_t *half_conns, streamid_t stream_id)
 
int connection_half_edge_is_valid_sendme (const smartlist_t *half_conns, streamid_t stream_id)
 
int connection_half_edge_is_valid_end (smartlist_t *half_conns, streamid_t stream_id)
 
int connection_half_edge_is_valid_resolved (smartlist_t *half_conns, streamid_t stream_id)
 
int connection_edge_end_errno (edge_connection_t *conn)
 
int connection_edge_flushed_some (edge_connection_t *conn)
 
int connection_edge_finished_flushing (edge_connection_t *conn)
 
STATIC int connected_cell_format_payload (uint8_t *payload_out, const tor_addr_t *addr, uint32_t ttl)
 
STATIC void export_hs_client_circuit_id (edge_connection_t *edge_conn, hs_circuit_id_protocol_t protocol)
 
int connection_edge_finished_connecting (edge_connection_t *edge_conn)
 
static void connection_edge_about_to_close (edge_connection_t *edge_conn)
 
void connection_ap_about_to_close (entry_connection_t *entry_conn)
 
void connection_exit_about_to_close (edge_connection_t *edge_conn)
 
static int compute_retry_timeout (entry_connection_t *conn)
 
void connection_ap_expire_beginning (void)
 
void connection_ap_rescan_and_attach_pending (void)
 
void connection_ap_attach_pending (int retry)
 
static void attach_pending_entry_connections_cb (mainloop_event_t *ev, void *arg)
 
void connection_ap_mark_as_pending_circuit_ (entry_connection_t *entry_conn, const char *fname, int lineno)
 
void connection_ap_mark_as_non_pending_circuit (entry_connection_t *entry_conn)
 
void connection_ap_mark_as_waiting_for_renddesc (entry_connection_t *entry_conn)
 
void connection_ap_warn_and_unmark_if_pending_circ (entry_connection_t *entry_conn, const char *where)
 
void connection_ap_fail_onehop (const char *failed_digest, cpath_build_state_t *build_state)
 
void circuit_discard_optional_exit_enclaves (extend_info_t *info)
 
void connection_entry_set_controller_wait (entry_connection_t *conn)
 
int connection_ap_detach_retriable (entry_connection_t *conn, origin_circuit_t *circ, int reason)
 
static int rend_valid_v2_service_id (const char *query)
 
STATIC bool parse_extended_hostname (char *address, hostname_type_t *type_out)
 
int connection_ap_rewrite_and_attach_if_allowed (entry_connection_t *conn, origin_circuit_t *circ, crypt_path_t *cpath)
 
STATIC void connection_ap_handshake_rewrite (entry_connection_t *conn, rewrite_result_t *out)
 
static int connection_ap_handle_onion (entry_connection_t *conn, socks_request_t *socks, origin_circuit_t *circ)
 
int connection_ap_handshake_rewrite_and_attach (entry_connection_t *conn, origin_circuit_t *circ, crypt_path_t *cpath)
 
static int connection_ap_get_original_destination (entry_connection_t *conn, socks_request_t *req)
 
int connection_ap_process_transparent (entry_connection_t *conn)
 
STATIC int connection_ap_process_http_connect (entry_connection_t *conn)
 
streamid_t get_unique_stream_id_by_circ (origin_circuit_t *circ)
 
static uint32_t connection_ap_get_begincell_flags (entry_connection_t *ap_conn)
 
int connection_ap_handshake_send_begin (entry_connection_t *ap_conn)
 
int connection_ap_handshake_send_resolve (entry_connection_t *ap_conn)
 
entry_connection_tconnection_ap_make_link (connection_t *partner, char *address, uint16_t port, const char *digest, int session_group, int isolation_flags, int use_begindir, int want_onehop)
 
static void tell_controller_about_resolved_result (entry_connection_t *conn, int answer_type, size_t answer_len, const char *answer, int ttl, time_t expires)
 
void connection_ap_handshake_socks_resolved_addr (entry_connection_t *conn, const tor_addr_t *answer, int ttl, time_t expires)
 
void connection_ap_handshake_socks_resolved (entry_connection_t *conn, int answer_type, size_t answer_len, const uint8_t *answer, int ttl, time_t expires)
 
void connection_ap_handshake_socks_reply (entry_connection_t *conn, char *reply, size_t replylen, int endreason)
 
STATIC int begin_cell_parse (const cell_t *cell, begin_cell_t *bcell, uint8_t *end_reason_out)
 
static int handle_hs_exit_conn (circuit_t *circ, edge_connection_t *conn)
 
int connection_exit_begin_conn (cell_t *cell, circuit_t *circ)
 
int connection_exit_begin_resolve (cell_t *cell, or_circuit_t *circ)
 
static int my_exit_policy_rejects (const tor_addr_t *addr, uint16_t port, const char **why_rejected)
 
void connection_exit_connect (edge_connection_t *edge_conn)
 
int connection_edge_is_rendezvous_stream (const edge_connection_t *conn)
 
int connection_ap_can_use_exit (const entry_connection_t *conn, const node_t *exit_node)
 
static int memeq_opt (const char *a, size_t alen, const char *b, size_t blen)
 
int connection_edge_compatible_with_circuit (const entry_connection_t *conn, const origin_circuit_t *circ)
 
int connection_edge_update_circuit_isolation (const entry_connection_t *conn, origin_circuit_t *circ, int dry_run)
 
void circuit_clear_isolation (origin_circuit_t *circ)
 
void connection_edge_end_close (edge_connection_t *conn, uint8_t reason)
 
void connection_edge_free_all (void)
 

Variables

static size_t n_half_conns_allocated = 0
 
static smartlist_tpending_entry_connections = NULL
 
static int untried_pending_connections = 0
 
static mainloop_event_tattach_pending_entry_connections_ev = NULL
 
static const char HTTP_CONNECT_IS_NOT_AN_HTTP_PROXY_MSG []
 

Detailed Description

Handle edge streams.

An edge_connection_t is a subtype of a connection_t, and represents two critical concepts in Tor: a stream, and an edge connection. From the Tor protocol's point of view, a stream is a bi-directional channel that is multiplexed on a single circuit. Each stream on a circuit is identified with a separate 16-bit stream ID, local to the (circuit,exit) pair. Streams are created in response to client requests.

An edge connection is one thing that can implement a stream: it is either a TCP application socket that has arrived via (e.g.) a SOCKS request, or an exit connection.

Not every instance of edge_connection_t truly represents an edge connection, however. (Sorry!) We also create edge_connection_t objects for streams that we will not be handling with TCP. The types of these streams are:

This module handles general-purpose functionality having to do with edge_connection_t. On the client side, it accepts various types of application requests on SocksPorts, TransPorts, and NATDPorts, and creates streams appropriately.

This module is also responsible for implementing stream isolation: ensuring that streams that should not be linkable to one another are kept to different circuits.

On the exit side, this module handles the various stream-creating type of RELAY cells by launching appropriate outgoing connections, DNS requests, or directory connection objects.

And for all edge connections, this module is responsible for handling incoming and outdoing data as it arrives or leaves in the relay.c module. (Outgoing data will be packaged in connection_edge_process_inbuf() as it calls connection_edge_package_raw_inbuf(); incoming data from RELAY_DATA cells is applied in connection_edge_process_relay_cell().)

Definition in file connection_edge.c.

Macro Definition Documentation

◆ MAX_CONNECTED_CELL_PAYLOAD_LEN

#define MAX_CONNECTED_CELL_PAYLOAD_LEN   25

Longest size for the relay payload of a RELAY_CONNECTED cell that we're able to generate.

Definition at line 867 of file connection_edge.c.

◆ TRACKHOSTEXITS_RETRIES

#define TRACKHOSTEXITS_RETRIES   5

How many times do we try connecting with an exit configured via TrackHostExits before concluding that it won't work any more and trying a different one?

Definition at line 1736 of file connection_edge.c.

Function Documentation

◆ begin_cell_parse()

STATIC int begin_cell_parse ( const cell_t cell,
begin_cell_t *  bcell,
uint8_t *  end_reason_out 
)

Read a RELAY_BEGIN or RELAY_BEGIN_DIR cell from cell, decode it, and place the result in bcell. On success return 0; on failure return <0 and set *end_reason_out to the end reason we should send back to the client.

Return -1 in the case where we want to send a RELAY_END cell, and < -1 when we don't.

Definition at line 3776 of file connection_edge.c.

◆ circuit_clear_isolation()

void circuit_clear_isolation ( origin_circuit_t circ)

Clear the isolation settings on circ.

This only works on an open circuit that has never had a stream attached to it, and whose isolation settings are hypothetical. (We set hypothetical isolation settings on circuits as we're launching them, so that we know whether they can handle more streams or whether we need to launch even more circuits. Once the circuit is open, if it turns out that we no longer have any streams to attach to it, we clear the isolation flags and data so that other streams can have a chance.)

Definition at line 4660 of file connection_edge.c.

Referenced by circuit_try_clearing_isolation_state().

◆ circuit_discard_optional_exit_enclaves()

void circuit_discard_optional_exit_enclaves ( extend_info_t info)

A circuit failed to finish on its last hop info. If there are any streams waiting with this exit node in mind, but they don't absolutely require it, make them give up on it.

Definition at line 1498 of file connection_edge.c.

◆ clip_dns_ttl()

uint32_t clip_dns_ttl ( uint32_t  ttl)

Given a TTL (in seconds) from a DNS response or from a relay, determine what TTL clients and relays should actually use for caching it.

Definition at line 473 of file connection_edge.c.

Referenced by client_dns_set_addressmap_impl(), connected_cell_format_payload(), and send_resolved_cell().

◆ compute_retry_timeout()

static int compute_retry_timeout ( entry_connection_t conn)
static

Define a schedule for how long to wait between retrying application connections. Rather than waiting a fixed amount of time between each retry, we wait 10 seconds each for the first two tries, and 15 seconds for each retry after that. Hopefully this will improve the expected user experience.

Definition at line 1097 of file connection_edge.c.

◆ connected_cell_format_payload()

STATIC int connected_cell_format_payload ( uint8_t *  payload_out,
const tor_addr_t addr,
uint32_t  ttl 
)

Set the buffer at payload_out – which must have at least MAX_CONNECTED_CELL_PAYLOAD_LEN bytes available – to the body of a RELAY_CONNECTED cell indicating that we have connected to addr, and that the name resolution that led us to addr will be valid for ttl seconds. Return -1 on error, or the number of bytes used on success.

Definition at line 876 of file connection_edge.c.

◆ connection_ap_about_to_close()

void connection_ap_about_to_close ( entry_connection_t entry_conn)

Called when we're about to finally unlink and free an AP (client) connection: perform necessary accounting and cleanup

Definition at line 1025 of file connection_edge.c.

Referenced by connection_about_to_close_connection().

◆ connection_ap_attach_pending()

void connection_ap_attach_pending ( int  retry)

Tell any AP streams that are listed as waiting for a new circuit to try again. If there is an available circuit for a stream, attach it. Otherwise, launch a new circuit.

If retry is false, only check the list if it contains at least one streams that we have not yet tried to attach to a circuit.

Definition at line 1289 of file connection_edge.c.

Referenced by circuit_try_attaching_streams().

◆ connection_ap_can_use_exit()

int connection_ap_can_use_exit ( const entry_connection_t conn,
const node_t exit_node 
)

Return 1 if router exit_node is likely to allow stream conn to exit from it, or 0 if it probably will not allow it. (We might be uncertain if conn's destination address has not yet been resolved.)

Definition at line 4428 of file connection_edge.c.

Referenced by circuit_stream_is_being_handled().

◆ connection_ap_detach_retriable()

int connection_ap_detach_retriable ( entry_connection_t conn,
origin_circuit_t circ,
int  reason 
)

The AP connection conn has just failed while attaching or sending a BEGIN or resolving on circ, but another circuit might work. Detach the circuit, and either reattach it, launch a new circuit, tell the controller, or give up as appropriate.

Returns -1 on err, 1 on success, 0 on not-yet-sure.

Definition at line 1559 of file connection_edge.c.

◆ connection_ap_expire_beginning()

void connection_ap_expire_beginning ( void  )

Find all general-purpose AP streams waiting for a response that sent their begin/resolve cell too long ago. Detach from their current circuit, and mark their current circuit as unsuitable for new streams. Then call connection_ap_handshake_attach_circuit() to attach to a new circuit (if available) or launch a new one.

For rendezvous streams, simply give up after SocksTimeout seconds (with no retry attempt).

Definition at line 1117 of file connection_edge.c.

Referenced by second_elapsed_callback().

◆ connection_ap_fail_onehop()

void connection_ap_fail_onehop ( const char *  failed_digest,
cpath_build_state_t build_state 
)

Tell any AP streams that are waiting for a one-hop tunnel to failed_digest that they are going to fail.

Definition at line 1457 of file connection_edge.c.

◆ connection_ap_get_begincell_flags()

static uint32_t connection_ap_get_begincell_flags ( entry_connection_t ap_conn)
static

Return a bitmask of BEGIN_FLAG_* flags that we should transmit in the RELAY_BEGIN cell for ap_conn.

Definition at line 3135 of file connection_edge.c.

◆ connection_ap_get_original_destination()

static int connection_ap_get_original_destination ( entry_connection_t conn,
socks_request_t req 
)
static

Fetch the original destination address and port from a system-specific interface and put them into a socks_request_t as if they came from a socks request.

Return -1 if an error prevents fetching the destination, else return 0.

Definition at line 2746 of file connection_edge.c.

◆ connection_ap_handle_onion()

static int connection_ap_handle_onion ( entry_connection_t conn,
socks_request_t socks,
origin_circuit_t circ 
)
static

We just received a SOCKS request in conn to a v3 onion. Start connecting to the onion service.

Definition at line 1962 of file connection_edge.c.

◆ connection_ap_handshake_process_socks()

static int connection_ap_handshake_process_socks ( entry_connection_t conn)
static

connection_edge_process_inbuf() found a conn in state socks_wait. See if conn->inbuf has the right bytes to proceed with the socks handshake.

If the handshake is complete, send it to connection_ap_handshake_rewrite_and_attach().

Return -1 if an unexpected error with conn occurs (and mark it for close), else return 0.

Definition at line 2786 of file connection_edge.c.

Referenced by connection_edge_process_inbuf().

◆ connection_ap_handshake_rewrite_and_attach()

int connection_ap_handshake_rewrite_and_attach ( entry_connection_t conn,
origin_circuit_t circ,
crypt_path_t cpath 
)

Connection conn just finished its socks handshake, or the controller asked us to take care of it. If circ is defined, then that's where we'll want to attach it. Otherwise we have to figure it out ourselves.

First, parse whether it's a .exit address, remap it, and so on. Then if it's for a general circuit, try to attach it to a circuit (or launch one as needed), else if it's for a rendezvous circuit, fetch a rendezvous descriptor first (or attach/launch a circuit if the rendezvous descriptor is already here and fresh enough).

The stream will exit from the hop indicated by cpath, or from the last hop in circ's cpath if cpath is NULL.

Definition at line 2096 of file connection_edge.c.

Referenced by connection_ap_rewrite_and_attach_if_allowed().

◆ connection_ap_handshake_send_begin()

int connection_ap_handshake_send_begin ( entry_connection_t ap_conn)

Write a relay begin cell, using destaddr and destport from ap_conn's socks_request field, and send it down circ.

If ap_conn is broken, mark it for close and return -1. Else return 0.

Definition at line 3198 of file connection_edge.c.

Referenced by connection_ap_handshake_attach_chosen_circuit().

◆ connection_ap_handshake_send_resolve()

int connection_ap_handshake_send_resolve ( entry_connection_t ap_conn)

Write a relay resolve cell, using destaddr and destport from ap_conn's socks_request field, and send it down circ.

If ap_conn is broken, mark it for close and return -1. Else return 0.

Definition at line 3318 of file connection_edge.c.

Referenced by connection_ap_handshake_attach_chosen_circuit().

◆ connection_ap_handshake_socks_reply()

void connection_ap_handshake_socks_reply ( entry_connection_t conn,
char *  reply,
size_t  replylen,
int  endreason 
)

Send a socks reply to stream conn, using the appropriate socks version, etc, and mark conn as completed with SOCKS handshaking.

If reply is defined, then write replylen bytes of it to conn and return, else reply based on endreason (one of END_STREAM_REASON_*). If reply is undefined, endreason can't be 0 or REASON_DONE. Send endreason to the controller, if appropriate.

Definition at line 3665 of file connection_edge.c.

◆ connection_ap_handshake_socks_resolved()

void connection_ap_handshake_socks_resolved ( entry_connection_t conn,
int  answer_type,
size_t  answer_len,
const uint8_t *  answer,
int  ttl,
time_t  expires 
)

Send an answer to an AP connection that has requested a DNS lookup via SOCKS. The type should be one of RESOLVED_TYPE_(IPV4|IPV6|HOSTNAME) or -1 for unreachable; the answer should be in the format specified in the socks extensions document. ttl is the ttl for the answer, or -1 on certain errors or for values that didn't come via DNS. expires is a time when the answer expires, or -1 or TIME_MAX if there's a good TTL.

Definition at line 3552 of file connection_edge.c.

Referenced by connection_ap_handshake_socks_resolved_addr().

◆ connection_ap_handshake_socks_resolved_addr()

void connection_ap_handshake_socks_resolved_addr ( entry_connection_t conn,
const tor_addr_t answer,
int  ttl,
time_t  expires 
)

As connection_ap_handshake_socks_resolved, but take a tor_addr_t to send as the answer.

Definition at line 3514 of file connection_edge.c.

◆ connection_ap_make_link()

entry_connection_t* connection_ap_make_link ( connection_t partner,
char *  address,
uint16_t  port,
const char *  digest,
int  session_group,
int  isolation_flags,
int  use_begindir,
int  want_onehop 
)

Make an AP connection_t linked to the connection_t partner. make a new linked connection pair, and attach one side to the conn, connection_add it, initialize it to circuit_wait, and call connection_ap_handshake_attach_circuit(conn) on it.

Return the newly created end of the linked connection pair, or -1 if error.

Definition at line 3408 of file connection_edge.c.

◆ connection_ap_mark_as_non_pending_circuit()

void connection_ap_mark_as_non_pending_circuit ( entry_connection_t entry_conn)

Mark entry_conn as no longer waiting for a circuit.

Definition at line 1415 of file connection_edge.c.

Referenced by connection_ap_mark_as_waiting_for_renddesc().

◆ connection_ap_mark_as_pending_circuit_()

void connection_ap_mark_as_pending_circuit_ ( entry_connection_t entry_conn,
const char *  fname,
int  lineno 
)

Mark entry_conn as needing to get attached to a circuit.

And entry_conn must be in AP_CONN_STATE_CIRCUIT_WAIT, should not already be pending a circuit. The circuit will get launched or the connection will get attached the next time we call connection_ap_attach_pending().

Definition at line 1371 of file connection_edge.c.

◆ connection_ap_mark_as_waiting_for_renddesc()

void connection_ap_mark_as_waiting_for_renddesc ( entry_connection_t entry_conn)

Mark entry_conn as waiting for a rendezvous descriptor. This function will remove the entry connection from the waiting for a circuit list (pending_entry_connections).

This pattern is used across the code base because a connection in state AP_CONN_STATE_RENDDESC_WAIT must not be in the pending list.

Definition at line 1430 of file connection_edge.c.

◆ connection_ap_process_http_connect()

STATIC int connection_ap_process_http_connect ( entry_connection_t conn)

Called on an HTTP CONNECT entry connection when some bytes have arrived, but we have not yet received a full HTTP CONNECT request. Try to parse an HTTP CONNECT request from the connection's inbuf. On success, set up the connection's socks_request field and try to attach the connection. On failure, send an HTTP reply, and mark the connection.

Definition at line 2985 of file connection_edge.c.

Referenced by connection_edge_process_inbuf().

◆ connection_ap_process_natd()

static int connection_ap_process_natd ( entry_connection_t conn)
static

connection_edge_process_inbuf() found a conn in state natd_wait. See if conn->inbuf has the right bytes to proceed. See FreeBSD's libalias(3) and ProxyEncodeTcpStream() in src/lib/libalias/alias_proxy.c for the encoding form of the original destination.

If the original destination is complete, send it to connection_ap_handshake_rewrite_and_attach().

Return -1 if an unexpected error with conn (and it should be marked for close), else return 0.

Definition at line 2888 of file connection_edge.c.

Referenced by connection_edge_process_inbuf().

◆ connection_ap_process_transparent()

int connection_ap_process_transparent ( entry_connection_t conn)

connection_init_accepted_conn() found a new trans AP conn. Get the original destination and send it to connection_ap_handshake_rewrite_and_attach().

Return -1 if an unexpected error with conn (and it should be marked for close), else return 0.

Definition at line 2848 of file connection_edge.c.

◆ connection_ap_rescan_and_attach_pending()

void connection_ap_rescan_and_attach_pending ( void  )

As connection_ap_attach_pending, but first scans the entire connection array to see if any elements are missing.

Definition at line 1242 of file connection_edge.c.

◆ connection_ap_rewrite_and_attach_if_allowed()

int connection_ap_rewrite_and_attach_if_allowed ( entry_connection_t conn,
origin_circuit_t circ,
crypt_path_t cpath 
)

Call connection_ap_handshake_rewrite_and_attach() unless a controller asked us to leave streams unattached. Return 0 in that case.

See connection_ap_handshake_rewrite_and_attach()'s documentation for arguments and return value.

Definition at line 1747 of file connection_edge.c.

◆ connection_ap_supports_optimistic_data()

static int connection_ap_supports_optimistic_data ( const entry_connection_t conn)
static

Return true iff conn is linked to a circuit and configured to use an exit that supports optimistic data.

Definition at line 3116 of file connection_edge.c.

◆ connection_edge_about_to_close()

static void connection_edge_about_to_close ( edge_connection_t edge_conn)
static

Common code to connection_(ap|exit)_about_to_close.

Definition at line 1011 of file connection_edge.c.

Referenced by connection_ap_about_to_close(), and connection_exit_about_to_close().

◆ connection_edge_compatible_with_circuit()

int connection_edge_compatible_with_circuit ( const entry_connection_t conn,
const origin_circuit_t circ 
)

Return true iff none of the isolation flags and fields in conn should prevent it from being attached to circ.

Definition at line 4512 of file connection_edge.c.

Referenced by circuit_stream_is_being_handled().

◆ connection_edge_destroy()

int connection_edge_destroy ( circid_t  circ_id,
edge_connection_t conn 
)

This edge needs to be closed, because its circuit has closed. Mark it for close and return 0.

Definition at line 394 of file connection_edge.c.

◆ connection_edge_end()

int connection_edge_end ( edge_connection_t conn,
uint8_t  reason 
)

Send a relay end cell from stream conn down conn's circuit, and remember that we've done so. If this is not a client connection, set the relay end cell's reason for closing as reason.

Return -1 if this function has already been called on this conn, else return 0.

Definition at line 493 of file connection_edge.c.

Referenced by connection_edge_end_close(), and inform_pending_connections().

◆ connection_edge_end_close()

void connection_edge_end_close ( edge_connection_t conn,
uint8_t  reason 
)

Send an END and mark for close the given edge connection conn using the given reason that has to be a stream reason.

Note: We don't unattached the AP connection (if applicable) because we don't want to flush the remaining data. This function aims at ending everything quickly regardless of the connection state.

This function can't fail and does nothing if conn is NULL.

Definition at line 4702 of file connection_edge.c.

◆ connection_edge_end_errno()

int connection_edge_end_errno ( edge_connection_t conn)

An error has just occurred on an operation on an edge connection conn. Extract the errno; convert it to an end reason, and send an appropriate relay end cell to the other end of the connection's circuit.

Definition at line 797 of file connection_edge.c.

◆ connection_edge_finished_connecting()

int connection_edge_finished_connecting ( edge_connection_t edge_conn)

Connected handler for exit connections: start writing pending data, deliver 'CONNECTED' relay cells as appropriate, and check any pending data that may have been received.

Definition at line 950 of file connection_edge.c.

Referenced by connection_finished_connecting().

◆ connection_edge_finished_flushing()

int connection_edge_finished_flushing ( edge_connection_t conn)

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

If it's in state 'open', stop writing, consider responding with a sendme, and return. Otherwise, stop writing and return.

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

Definition at line 838 of file connection_edge.c.

Referenced by connection_finished_flushing().

◆ connection_edge_flushed_some()

int connection_edge_flushed_some ( edge_connection_t conn)

We just wrote some data to conn; act appropriately.

(That is, if it's open, consider sending a stream-level sendme cell if we have just flushed enough.)

Definition at line 811 of file connection_edge.c.

◆ connection_edge_free_all()

void connection_edge_free_all ( void  )

Free all storage held in module-scoped variables for connection_edge.c

Definition at line 4714 of file connection_edge.c.

◆ connection_edge_is_rendezvous_stream()

int connection_edge_is_rendezvous_stream ( const edge_connection_t conn)

Return 1 if conn is a rendezvous stream, or 0 if it is a general stream.

Definition at line 4412 of file connection_edge.c.

Referenced by ap_stream_wants_exit_attention(), connection_exit_connect(), hs_client_note_connection_attempt_succeeded(), and write_stream_target_to_buf().

◆ connection_edge_process_inbuf()

int connection_edge_process_inbuf ( edge_connection_t conn,
int  package_partial 
)

Handle new bytes on conn->inbuf based on state:

  • If it's waiting for socks info, try to read another step of the socks handshake out of conn->inbuf.
  • If it's waiting for the original destination, fetch it.
  • If it's open, then package more relay cells from the stream.
  • Else, leave the bytes on inbuf alone for now.

Mark and return -1 if there was an unexpected error with the conn, else return 0.

Definition at line 320 of file connection_edge.c.

Referenced by connection_process_inbuf().

◆ connection_edge_reached_eof()

int connection_edge_reached_eof ( edge_connection_t conn)

There was an EOF. Send an end and mark the connection for close.

Definition at line 286 of file connection_edge.c.

Referenced by connection_reached_eof().

◆ connection_edge_update_circuit_isolation()

int connection_edge_update_circuit_isolation ( const entry_connection_t conn,
origin_circuit_t circ,
int  dry_run 
)

If dry_run is false, update circ's isolation flags and fields to reflect having had conn attached to it, and return 0. Otherwise, if dry_run is true, then make no changes to circ, and return a bitfield of isolation flags that we would have to set in isolation_flags_mixed to add conn to circ, or -1 if circ has had no streams attached to it.

Definition at line 4582 of file connection_edge.c.

◆ connection_entry_set_controller_wait()

void connection_entry_set_controller_wait ( entry_connection_t conn)

Set the connection state to CONTROLLER_WAIT and send an control port event.

Definition at line 1544 of file connection_edge.c.

Referenced by connection_ap_rewrite_and_attach_if_allowed().

◆ connection_exit_about_to_close()

void connection_exit_about_to_close ( edge_connection_t edge_conn)

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

Definition at line 1076 of file connection_edge.c.

Referenced by connection_about_to_close_connection().

◆ connection_exit_begin_conn()

int connection_exit_begin_conn ( cell_t cell,
circuit_t circ 
)

A relay 'begin' or 'begin_dir' cell has arrived, and either we are an exit hop for the circuit, or we are the origin and it is a rendezvous begin.

Launch a new exit connection and initialize things appropriately.

If it's a rendezvous stream, call connection_exit_connect() on it.

For general streams, call dns_resolve() on it first, and only call connection_exit_connect() if the dns answer is already known.

Note that we don't call connection_add() on the new stream! We wait for connection_exit_connect() to do that.

Return -(some circuit end reason) if we want to tear down circ. Else return 0.

Definition at line 3938 of file connection_edge.c.

◆ connection_exit_begin_resolve()

int connection_exit_begin_resolve ( cell_t cell,
or_circuit_t circ 
)

Called when we receive a RELAY_COMMAND_RESOLVE cell 'cell' along the circuit circ; begin resolving the hostname, and (eventually) reply with a RESOLVED cell.

Definition at line 4134 of file connection_edge.c.

◆ connection_exit_connect()

void connection_exit_connect ( edge_connection_t edge_conn)

Connect to conn's specified addr and port. If it worked, conn has now been added to the connection_array.

Send back a connected cell. Include the resolved IP of the destination address, but only if it's a general exit stream. (Rendezvous streams must not reveal what IP they connected to.)

Definition at line 4213 of file connection_edge.c.

◆ connection_exit_connect_dir()

static int connection_exit_connect_dir ( edge_connection_t exitconn)
static

Given an exit conn that should attach to us as a directory server, open a bridge connection with a linked connection pair, create a new directory conn, and join them together. Return 0 on success (or if there was an error we could send back an end cell for). Return -(some circuit end reason) if the circuit needs to be torn down. Either connects exitconn, frees it, or marks it, as appropriate.

Definition at line 4352 of file connection_edge.c.

◆ connection_half_edge_add()

STATIC void connection_half_edge_add ( const edge_connection_t conn,
origin_circuit_t circ 
)

Add a half-closed connection to the list, to watch for activity.

These connections are removed from the list upon receiving an end cell.

Definition at line 592 of file connection_edge.c.

◆ connection_half_edge_compare_bsearch()

static int connection_half_edge_compare_bsearch ( const void *  key,
const void **  member 
)
static

Helper function for bsearch.

As per smartlist_bsearch, return < 0 if key precedes member,

0 if member precedes key, and 0 if they are equal.

This is equivalent to subtraction of the values of key - member (why does no one ever say that explicitly?).

Definition at line 572 of file connection_edge.c.

Referenced by connection_half_edge_find_stream_id(), and connection_half_edge_is_valid_end().

◆ connection_half_edge_find_stream_id()

STATIC half_edge_t* connection_half_edge_find_stream_id ( const smartlist_t half_conns,
streamid_t  stream_id 
)

Find a stream_id_t in the list in O(lg(n)).

Returns NULL if the list is empty or element is not found. Returns a pointer to the element if found.

Definition at line 663 of file connection_edge.c.

Referenced by connection_half_edge_add(), connection_half_edge_is_valid_connected(), connection_half_edge_is_valid_data(), and connection_half_edge_is_valid_sendme().

◆ connection_half_edge_is_valid_connected()

int connection_half_edge_is_valid_connected ( const smartlist_t half_conns,
streamid_t  stream_id 
)

Check if this stream_id is in a half-closed state. If so, check if it still has a connected cell pending, and decrement that window if so.

Return 1 if the connected window was not empty. Return 0 otherwise.

Definition at line 708 of file connection_edge.c.

◆ connection_half_edge_is_valid_data()

int connection_half_edge_is_valid_data ( const smartlist_t half_conns,
streamid_t  stream_id 
)

Check if this stream_id is in a half-closed state. If so, check if it still has data cells pending, and decrement that window if so.

Return 1 if the data window was not empty. Return 0 otherwise.

Definition at line 682 of file connection_edge.c.

◆ connection_half_edge_is_valid_end()

int connection_half_edge_is_valid_end ( smartlist_t half_conns,
streamid_t  stream_id 
)

Check if this stream_id is in a half-closed state. If so, remove it from the list. No other data should come after the END cell.

Return 1 if stream_id was in half-closed state. Return 0 otherwise.

Definition at line 759 of file connection_edge.c.

Referenced by connection_half_edge_is_valid_resolved().

◆ connection_half_edge_is_valid_resolved()

int connection_half_edge_is_valid_resolved ( smartlist_t half_conns,
streamid_t  stream_id 
)

Streams that were used to send a RESOLVE cell are closed when they get the RESOLVED, without an end. So treat a RESOLVED just like an end, and remove from the list.

Definition at line 786 of file connection_edge.c.

◆ connection_half_edge_is_valid_sendme()

int connection_half_edge_is_valid_sendme ( const smartlist_t half_conns,
streamid_t  stream_id 
)

Check if this stream_id is in a half-closed state. If so, check if it still has sendme cells pending, and decrement that window if so.

Return 1 if the sendme window was not empty. Return 0 otherwise.

Definition at line 734 of file connection_edge.c.

◆ connection_mark_unattached_ap_()

void connection_mark_unattached_ap_ ( entry_connection_t conn,
int  endreason,
int  line,
const char *  file 
)

An AP stream has failed/finished. If it hasn't already sent back a socks reply, send one now (based on endreason). Also set has_sent_end to 1, and mark the conn.

Definition at line 250 of file connection_edge.c.

◆ consider_plaintext_ports()

static int consider_plaintext_ports ( entry_connection_t conn,
uint16_t  port 
)
static

Check if conn is using a dangerous port. Then warn and/or reject depending on our config options.

Definition at line 1591 of file connection_edge.c.

◆ CONST_EDGE_TO_ENTRY_CONN()

const entry_connection_t* CONST_EDGE_TO_ENTRY_CONN ( const edge_connection_t c)

Cast a const edge_connection_t * to a const entry_connection_t *.

Exit with an assertion failure if the input is not an entry_connection_t.

Definition at line 239 of file connection_edge.c.

◆ CONST_TO_EDGE_CONN()

const edge_connection_t* CONST_TO_EDGE_CONN ( const connection_t c)

Cast a const connection_t * to a const edge_connection_t *.

Exit with an assertion failure if the input is not an edge_connection_t.

Definition at line 189 of file connection_edge.c.

◆ CONST_TO_ENTRY_CONN()

const entry_connection_t* CONST_TO_ENTRY_CONN ( const connection_t c)

Cast a const connection_t * to a const entry_connection_t *.

Exit with an assertion failure if the input is not an entry_connection_t.

Definition at line 214 of file connection_edge.c.

◆ EDGE_TO_ENTRY_CONN()

entry_connection_t* EDGE_TO_ENTRY_CONN ( edge_connection_t c)

◆ get_unique_stream_id_by_circ()

streamid_t get_unique_stream_id_by_circ ( origin_circuit_t circ)

Iterate over the two bytes of stream_id until we get one that is not already in use; return it. Return 0 if can't get a unique stream_id.

Definition at line 3087 of file connection_edge.c.

◆ half_edge_free_()

void half_edge_free_ ( half_edge_t he)

Release space held by he

Definition at line 641 of file connection_edge.c.

◆ half_streams_get_total_allocation()

size_t half_streams_get_total_allocation ( void  )

Return the number of bytes devoted to storing info on half-open streams.

Definition at line 651 of file connection_edge.c.

◆ handle_hs_exit_conn()

static int handle_hs_exit_conn ( circuit_t circ,
edge_connection_t conn 
)
static

For the given circ and the edge connection conn, setup the connection, attach it to the circ and connect it. Return 0 on success or END_CIRC_AT_ORIGIN if we can't find the requested hidden service port where the caller should close the circuit.

Definition at line 3836 of file connection_edge.c.

◆ memeq_opt()

static int memeq_opt ( const char *  a,
size_t  alen,
const char *  b,
size_t  blen 
)
static

Return true iff the (possibly NULL) alen-byte chunk of memory at a is equal to the (possibly NULL) blen-byte chunk of memory at b.

Definition at line 4494 of file connection_edge.c.

◆ my_exit_policy_rejects()

static int my_exit_policy_rejects ( const tor_addr_t addr,
uint16_t  port,
const char **  why_rejected 
)
static

Helper: Return true and set *why_rejected to an optional clarifying message message iff we do not allow connections to addr:port.

Definition at line 4182 of file connection_edge.c.

Referenced by connection_exit_connect().

◆ network_reentry_is_allowed()

static bool network_reentry_is_allowed ( void  )
static

Return true iff the consensus allows network reentry. The default value is false if the parameter is not found.

Definition at line 4199 of file connection_edge.c.

◆ parse_extended_hostname()

STATIC bool parse_extended_hostname ( char *  address,
hostname_type_t type_out 
)

Parse the given hostname in address. Returns true if the parsing was successful and type_out contains the type of the hostname. Else, false is returned which means it was not recognized and type_out is set to BAD_HOSTNAME.

The possible recognized forms are (where true is returned):

If address is of the form "y.onion" with a well-formed handle y: Put a NUL after y, lower-case it, and return ONION_V3_HOSTNAME depending on the HS version.

If address is of the form "x.y.onion" with a well-formed handle x: Drop "x.", put a NUL after y, lower-case it, and return ONION_V3_HOSTNAME depending on the HS version.

If address is of the form "y.onion" with a badly-formed handle y: Return BAD_HOSTNAME and log a message.

If address is of the form "y.exit": Put a NUL after y and return EXIT_HOSTNAME.

Otherwise: Return NORMAL_HOSTNAME and change nothing.

Definition at line 1657 of file connection_edge.c.

◆ relay_send_end_cell_from_edge()

static int relay_send_end_cell_from_edge ( streamid_t  stream_id,
circuit_t circ,
uint8_t  reason,
crypt_path_t cpath_layer 
)
static

Send a raw end cell to the stream with ID stream_id out over the circ towards the hop identified with cpath_layer. If this is not a client connection, set the relay end cell's reason for closing as reason

Definition at line 424 of file connection_edge.c.

◆ rend_valid_v2_service_id()

static int rend_valid_v2_service_id ( const char *  query)
static

Return true iff query is a syntactically valid service ID (as generated by rend_get_service_id).

Length of 'y' portion of 'y.onion' URL.

Definition at line 1618 of file connection_edge.c.

◆ tell_controller_about_resolved_result()

static void tell_controller_about_resolved_result ( entry_connection_t conn,
int  answer_type,
size_t  answer_len,
const char *  answer,
int  ttl,
time_t  expires 
)
static

Notify any interested controller connections about a new hostname resolve or resolve error. Takes the same arguments as does connection_ap_handshake_socks_resolved().

Definition at line 3475 of file connection_edge.c.

◆ TO_EDGE_CONN()

edge_connection_t* TO_EDGE_CONN ( connection_t c)

◆ TO_ENTRY_CONN()

entry_connection_t* TO_ENTRY_CONN ( connection_t c)

Variable Documentation

◆ attach_pending_entry_connections_ev

mainloop_event_t* attach_pending_entry_connections_ev = NULL
static

Mainloop event to tell us to scan for pending connections that can be attached.

Definition at line 1007 of file connection_edge.c.

◆ HTTP_CONNECT_IS_NOT_AN_HTTP_PROXY_MSG

const char HTTP_CONNECT_IS_NOT_AN_HTTP_PROXY_MSG[]
static
Initial value:
=
"HTTP/1.0 405 Method Not Allowed\r\n"
"Content-Type: text/html; charset=iso-8859-1\r\n\r\n"
"<html>\n"
"<head>\n"
"<title>This is an HTTP CONNECT tunnel, not a full HTTP Proxy</title>\n"
"</head>\n"
"<body>\n"
"<h1>This is an HTTP CONNECT tunnel, not an HTTP proxy.</h1>\n"
"<p>\n"
"It appears you have configured your web browser to use this Tor port as\n"
"an HTTP proxy.\n"
"</p><p>\n"
"This is not correct: This port is configured as a CONNECT tunnel, not\n"
"an HTTP proxy. Please configure your client accordingly. You can also\n"
"use HTTPS; then the client should automatically use HTTP CONNECT."
"</p>\n"
"<p>\n"
"See <a href=\"https://www.torproject.org/documentation.html\">"
"https://www.torproject.org/documentation.html</a> for more "
"information.\n"
"</p>\n"
"</body>\n"
"</html>\n"

Definition at line 2953 of file connection_edge.c.

◆ n_half_conns_allocated

size_t n_half_conns_allocated = 0
static

Total number of half_edge_t objects allocated

Definition at line 583 of file connection_edge.c.

Referenced by half_edge_free_(), and half_streams_get_total_allocation().

◆ pending_entry_connections

smartlist_t* pending_entry_connections = NULL
static

A list of all the entry_connection_t * objects that are not marked for close, and are in AP_CONN_STATE_CIRCUIT_WAIT.

(Right now, we check in several places to make sure that this list is correct. When it's incorrect, we'll fix it, and log a BUG message.)

Definition at line 999 of file connection_edge.c.