connection_edge.c File Reference

Handle edge streams. More...

#include "or.h"
#include <linux/types.h>
#include <linux/netfilter_ipv4.h>

Data Structures

struct  addressmap_entry_t
struct  virtaddress_entry_t

Defines

#define TRANS_NETFILTER
#define SOCKS4_GRANTED   90
#define SOCKS4_REJECT   91
#define TRACKHOSTEXITS_RETRIES   5

Functions

static int connection_ap_handshake_process_socks (edge_connection_t *conn)
static int connection_ap_process_natd (edge_connection_t *conn)
static int connection_exit_connect_dir (edge_connection_t *exitconn)
static int address_is_in_virtual_range (const char *addr)
static int consider_plaintext_ports (edge_connection_t *conn, uint16_t port)
static void clear_trackexithost_mappings (const char *exitname)
void _connection_mark_unattached_ap (edge_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)
int connection_edge_end (edge_connection_t *conn, uint8_t reason)
int connection_edge_end_errno (edge_connection_t *conn)
int connection_edge_finished_flushing (edge_connection_t *conn)
int connection_edge_finished_connecting (edge_connection_t *edge_conn)
static int compute_retry_timeout (edge_connection_t *conn)
void connection_ap_expire_beginning (void)
void connection_ap_attach_pending (void)
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)
int connection_ap_detach_retriable (edge_connection_t *conn, origin_circuit_t *circ, int reason)
void addressmap_init (void)
static void addressmap_ent_free (void *_ent)
static void addressmap_virtaddress_ent_free (void *_ent)
static void addressmap_virtaddress_remove (const char *address, addressmap_entry_t *ent)
static void addressmap_ent_remove (const char *address, addressmap_entry_t *ent)
void addressmap_clear_configured (void)
void addressmap_clear_transient (void)
void addressmap_clean (time_t now)
void addressmap_free_all (void)
int addressmap_rewrite (char *address, size_t maxlen, time_t *expires_out)
static int addressmap_rewrite_reverse (char *address, size_t maxlen, time_t *expires_out)
int addressmap_have_mapping (const char *address, int update_expiry)
void addressmap_register (const char *address, char *new_address, time_t expires, addressmap_entry_source_t source)
int client_dns_incr_failures (const char *address)
void client_dns_clear_failures (const char *address)
static void client_dns_set_addressmap_impl (const char *address, const char *name, const char *exitname, int ttl)
void client_dns_set_addressmap (const char *address, uint32_t val, const char *exitname, int ttl)
static void client_dns_set_reverse_addressmap (const char *address, const char *v, const char *exitname, int ttl)
int parse_virtual_addr_network (const char *val, int validate_only, char **msg)
static char * addressmap_get_virtual_address (int type)
const char * addressmap_register_virtual_address (int type, char *new_address)
int address_is_invalid_destination (const char *address, int client)
void addressmap_get_mappings (smartlist_t *sl, time_t min_expires, time_t max_expires, int want_expiry)
int connection_ap_handshake_rewrite_and_attach (edge_connection_t *conn, origin_circuit_t *circ, crypt_path_t *cpath)
static int connection_ap_get_original_destination (edge_connection_t *conn, socks_request_t *req)
int connection_ap_process_transparent (edge_connection_t *conn)
static streamid_t get_unique_stream_id_by_circ (origin_circuit_t *circ)
int connection_ap_handshake_send_begin (edge_connection_t *ap_conn)
int connection_ap_handshake_send_resolve (edge_connection_t *ap_conn)
edge_connection_tconnection_ap_make_link (char *address, uint16_t port, const char *digest, int use_begindir, int want_onehop)
static void tell_controller_about_resolved_result (edge_connection_t *conn, int answer_type, size_t answer_len, const char *answer, int ttl, time_t expires)
void connection_ap_handshake_socks_resolved (edge_connection_t *conn, int answer_type, size_t answer_len, const char *answer, int ttl, time_t expires)
void connection_ap_handshake_socks_reply (edge_connection_t *conn, char *reply, size_t replylen, int endreason)
int connection_exit_begin_conn (cell_t *cell, circuit_t *circ)
int connection_exit_begin_resolve (cell_t *cell, or_circuit_t *circ)
void connection_exit_connect (edge_connection_t *edge_conn)
int connection_edge_is_rendezvous_stream (edge_connection_t *conn)
int connection_ap_can_use_exit (edge_connection_t *conn, routerinfo_t *exit, int excluded_means_no)
hostname_type_t parse_extended_hostname (char *address, int allowdotexit)

Variables

static strmap_t * addressmap = NULL
static strmap_t * virtaddress_reversemap = NULL
static uint32_t virtual_addr_network = 0x7fc00000u
static maskbits_t virtual_addr_netmask_bits = 10
static uint32_t next_virtual_addr = 0x7fc00000u


Detailed Description

Handle edge streams.


Define Documentation

#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?


Function Documentation

void _connection_mark_unattached_ap ( edge_connection_t conn,
int  endreason,
int  line,
const char *  file 
)

static int address_is_in_virtual_range ( const char *  address  )  [static]

Return true iff addr is likely to have been returned by client_dns_get_unused_address.

References addr_mask_cmp_bits(), strcasecmpend(), tor_assert, tor_inet_aton(), virtual_addr_netmask_bits, and virtual_addr_network.

Referenced by addressmap_register(), and addressmap_virtaddress_remove().

int address_is_invalid_destination ( const char *  address,
int  client 
)

Return 1 if address has funny characters in it like colons. Return 0 if it's fine, or if we're configured to allow it anyway. client should be true if we're using this address as a client; false if we're using it as a server.

References get_options().

Referenced by config_register_addressmaps(), dns_resolve_impl(), and handle_control_mapaddress().

void addressmap_clean ( time_t  now  ) 

Clean out entries from the addressmap cache that were added long enough ago that they are no longer valid.

References addressmap_get_mappings().

Referenced by circuit_build_needed_circs().

void addressmap_clear_configured ( void   ) 

Remove all entries from the addressmap that were set via the configuration file or the command line.

References addressmap_get_mappings().

Referenced by config_register_addressmaps().

void addressmap_clear_transient ( void   ) 

Remove all entries from the addressmap that are set to expire, ever.

References addressmap_get_mappings().

Referenced by do_hup(), signal_callback(), and signewnym_impl().

static void addressmap_ent_free ( void *  _ent  )  [static]

Free the memory associated with the addressmap entry _ent.

References addressmap_entry_t::new_address, and tor_free.

Referenced by addressmap_ent_remove(), and addressmap_free_all().

static void addressmap_ent_remove ( const char *  address,
addressmap_entry_t ent 
) [static]

Remove ent (which must be mapped to by address) from the client address maps.

References addressmap_ent_free(), and addressmap_virtaddress_remove().

Referenced by addressmap_get_mappings(), addressmap_register(), and clear_trackexithost_mappings().

void addressmap_free_all ( void   ) 

Free all the elements in the addressmap, and free the addressmap itself.

References addressmap, addressmap_ent_free(), addressmap_virtaddress_ent_free(), strmap_free(), and virtaddress_reversemap.

Referenced by tor_free_all().

void addressmap_get_mappings ( smartlist_t sl,
time_t  min_expires,
time_t  max_expires,
int  want_expiry 
)

Iterate over all address mappings which have expiry times between min_expires and max_expires, inclusive. If sl is provided, add an "old-addr new-addr expiry" string to sl for each mapping, omitting the expiry time if want_expiry is false. If sl is NULL, remove the mappings.

References addressmap, addressmap_ent_remove(), addressmap_init(), addressmap_entry_t::expires, format_iso_time(), addressmap_entry_t::new_address, smartlist_add(), strmap_iter_done(), strmap_iter_get(), strmap_iter_init(), strmap_iter_next(), strmap_iter_next_rmv(), and tor_snprintf().

Referenced by addressmap_clean(), addressmap_clear_configured(), addressmap_clear_transient(), and getinfo_helper_events().

static char* addressmap_get_virtual_address ( int  type  )  [static]

Return a newly allocated string holding an address of type (one of RESOLVED_TYPE_{IPV4|HOSTNAME}) that has not yet been mapped, and that is very unlikely to be the address of any real host.

References addr_mask_cmp_bits(), addressmap, base32_encode(), crypto_rand(), LD_BUG, LD_CONFIG, next_virtual_addr, strmap_get(), tor_assert, tor_inet_ntoa(), virtual_addr_netmask_bits, and virtual_addr_network.

Referenced by addressmap_register_virtual_address().

int addressmap_have_mapping ( const char *  address,
int  update_expiry 
)

Return 1 if address is already registered, else return 0. If address is already registered, and update_expires is non-zero, then update the expiry time on the mapping with update_expires if it is a mapping created by TrackHostExits.

References addressmap, ADDRMAPSRC_TRACKEXIT, addressmap_entry_t::expires, addressmap_entry_t::source, and strmap_get_lc().

Referenced by consider_recording_trackhost(), and fetch_from_buf_socks().

void addressmap_init ( void   ) 

Initialize addressmap.

References addressmap, and virtaddress_reversemap.

Referenced by addressmap_get_mappings(), and tor_init().

void addressmap_register ( const char *  address,
char *  new_address,
time_t  expires,
addressmap_entry_source_t  source 
)

Register a request to map address to new_address, which will expire on expires (or 0 if never expires from config file, 1 if never expires from controller, 2 if never expires (virtual address mapping) from the controller.)

new_address should be a newly dup'ed string, which we'll use or free as appropriate. We will leave address alone.

If new_address is NULL, or equal to address, remove any mappings that exist from address.

References address_is_in_virtual_range(), addressmap, addressmap_ent_remove(), addressmap_virtaddress_remove(), control_event_address_mapped(), addressmap_entry_t::expires, LD_APP, LD_CONFIG, addressmap_entry_t::new_address, addressmap_entry_t::num_resolve_failures, safe_str_client(), addressmap_entry_t::source, strmap_get(), strmap_remove(), strmap_set(), and tor_free.

Referenced by addressmap_register_virtual_address(), client_dns_set_addressmap_impl(), config_register_addressmaps(), and handle_control_mapaddress().

const char* addressmap_register_virtual_address ( int  type,
char *  new_address 
)

A controller has requested that we map some address of type type to the address new_address. Choose an address that is unlikely to be used, and map it, and return it in a newly allocated string. If another address of the same type is already mapped to new_address, try to return a copy of that address.

The string in new_address may be freed, or inserted into a map as appropriate.

References addressmap, addressmap_get_virtual_address(), addressmap_register(), ADDRMAPSRC_CONTROLLER, virtaddress_entry_t::hostname_address, virtaddress_entry_t::ipv4_address, LD_APP, LD_BUG, addressmap_entry_t::new_address, safe_str_client(), strmap_get(), strmap_set(), tor_assert, tor_free, and virtaddress_reversemap.

Referenced by connection_ap_handshake_rewrite_and_attach(), and handle_control_mapaddress().

int addressmap_rewrite ( char *  address,
size_t  maxlen,
time_t *  expires_out 
)

Look at address, and rewrite it until it doesn't want any more rewrites; but don't get into an infinite loop. Don't write more than maxlen chars into address. Return true if the address changed; false otherwise. Set *expires_out to the expiry time of the result, or to time_max if the result does not expire.

References addressmap, escaped_safe_str_client(), addressmap_entry_t::expires, LD_APP, LD_CONFIG, addressmap_entry_t::new_address, strmap_get(), and tor_free.

Referenced by connection_ap_process_end_not_open().

static int addressmap_rewrite_reverse ( char *  address,
size_t  maxlen,
time_t *  expires_out 
) [static]

If we have a cached reverse DNS entry for the address stored in the maxlen-byte buffer address (typically, a dotted quad) then rewrite to the cached value and return 1. Otherwise return 0. Set *expires_out to the expiry time of the result, or to time_max if the result does not expire.

References addressmap, escaped_safe_str_client(), addressmap_entry_t::expires, LD_APP, addressmap_entry_t::new_address, strmap_get(), tor_free, and tor_snprintf().

static void addressmap_virtaddress_ent_free ( void *  _ent  )  [static]

Free storage held by a virtaddress_entry_t* entry in ent.

References virtaddress_entry_t::hostname_address, virtaddress_entry_t::ipv4_address, and tor_free.

Referenced by addressmap_free_all().

static void addressmap_virtaddress_remove ( const char *  address,
addressmap_entry_t ent 
) [static]

void circuit_discard_optional_exit_enclaves ( extend_info_t info  ) 

static void clear_trackexithost_mappings ( const char *  exitname  )  [static]

Unregister all TrackHostExits mappings from any address to *.exitname.exit.

References addressmap, addressmap_ent_remove(), ADDRMAPSRC_TRACKEXIT, strcmpend(), tor_free, tor_snprintf(), and tor_strlower().

Referenced by circuit_discard_optional_exit_enclaves().

void client_dns_clear_failures ( const char *  address  ) 

If address is in the client DNS addressmap, reset the number of resolve failures we have on record for it. This is used when we fail a stream because it won't resolve: otherwise future attempts on that address will only try once.

References addressmap, addressmap_entry_t::num_resolve_failures, and strmap_get().

Referenced by connection_ap_process_end_not_open().

int client_dns_incr_failures ( const char *  address  ) 

An attempt to resolve address failed at some OR. Increment the number of resolve failures we have on record for it, and then return that number.

References addressmap, addressmap_entry_t::expires, LD_APP, MAX_DNS_ENTRY_AGE, addressmap_entry_t::num_resolve_failures, safe_str_client(), strmap_get(), and strmap_set().

Referenced by connection_ap_process_end_not_open().

void client_dns_set_addressmap ( const char *  address,
uint32_t  val,
const char *  exitname,
int  ttl 
)

Record the fact that address resolved to val. We can now use this in subsequent streams via addressmap_rewrite() so we can more correctly choose an exit that will allow address.

If exitname is defined, then append the addresses with ".exitname.exit" before registering the mapping.

If ttl is nonnegative, the mapping will be valid for ttlseconds; otherwise, we use the default.

References client_dns_set_addressmap_impl(), INET_NTOA_BUF_LEN, tor_assert, tor_inet_aton(), and tor_inet_ntoa().

Referenced by connection_ap_handshake_socks_resolved(), connection_ap_process_end_not_open(), and connection_edge_process_relay_cell_not_open().

static void client_dns_set_addressmap_impl ( const char *  address,
const char *  name,
const char *  exitname,
int  ttl 
) [static]

Record the fact that address resolved to name. We can now use this in subsequent streams via addressmap_rewrite() so we can more correctly choose an exit that will allow address.

If exitname is defined, then append the addresses with ".exitname.exit" before registering the mapping.

If ttl is nonnegative, the mapping will be valid for ttlseconds; otherwise, we use the default.

References addressmap_register(), ADDRMAPSRC_DNS, DEFAULT_DNS_TTL, dns_clip_ttl(), INET_NTOA_BUF_LEN, MAX_VERBOSE_NICKNAME_LEN, tor_assert, and tor_snprintf().

Referenced by client_dns_set_addressmap(), and client_dns_set_reverse_addressmap().

static void client_dns_set_reverse_addressmap ( const char *  address,
const char *  v,
const char *  exitname,
int  ttl 
) [static]

Add a cache entry noting that address (ordinarily a dotted quad) resolved via a RESOLVE_PTR request to the hostname v.

If exitname is defined, then append the addresses with ".exitname.exit" before registering the mapping.

If ttl is nonnegative, the mapping will be valid for ttlseconds; otherwise, we use the default.

References client_dns_set_addressmap_impl(), tor_free, and tor_snprintf().

Referenced by connection_ap_handshake_socks_resolved().

static int compute_retry_timeout ( edge_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.

References or_options_t::CircuitStreamTimeout, get_options(), and edge_connection_t::num_socks_retries.

Referenced by connection_ap_expire_beginning().

void connection_ap_attach_pending ( void   ) 

int connection_ap_can_use_exit ( edge_connection_t conn,
routerinfo_t exit,
int  excluded_means_no 
)

int connection_ap_detach_retriable ( edge_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 a appropriate.

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

References edge_connection_t::_base, AP_CONN_STATE_CIRCUIT_WAIT, AP_CONN_STATE_CONTROLLER_WAIT, circuit_detach_stream(), connection_ap_handshake_attach_circuit(), control_event_stream_status(), get_options(), connection_t::state, connection_t::timestamp_lastread, TO_CIRCUIT, and edge_connection_t::use_begindir.

Referenced by connection_ap_expire_beginning(), and connection_ap_process_end_not_open().

void connection_ap_expire_beginning ( void   ) 

void connection_ap_fail_onehop ( const char *  failed_digest,
cpath_build_state_t build_state 
)

static int connection_ap_get_original_destination ( edge_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.

References edge_connection_t::_base, connection_t::addr, socks_request_t::address, LD_BUG, LD_NET, connection_t::port, socks_request_t::port, connection_t::s, tor_addr_from_in6(), tor_addr_from_ipv4n(), tor_addr_from_sockaddr(), tor_addr_to_in6(), tor_addr_to_ipv4n(), tor_addr_to_str(), and tor_fragile_assert.

Referenced by connection_ap_process_transparent().

static int connection_ap_handshake_process_socks ( edge_connection_t conn  )  [static]

int connection_ap_handshake_rewrite_and_attach ( edge_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.

References socks_request_t::address, addressmap_register_virtual_address(), or_options_t::AutomapHostsOnResolve, or_options_t::AutomapHostsSuffixes, socks_request_t::command, escaped_safe_str_client(), get_options(), LD_APP, socks_request_t::port, safe_str_client(), SOCKS_COMMAND_RESOLVE, edge_connection_t::socks_request, strcasecmpend(), tor_assert, tor_inet_aton(), and tor_strlower().

Referenced by connection_ap_handshake_process_socks(), connection_ap_process_natd(), connection_ap_process_transparent(), dnsserv_launch_request(), evdns_server_callback(), and handle_control_attachstream().

int connection_ap_handshake_send_begin ( edge_connection_t ap_conn  ) 

int connection_ap_handshake_send_resolve ( edge_connection_t ap_conn  ) 

void connection_ap_handshake_socks_reply ( edge_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.

References control_event_stream_status(), socks_request_t::has_finished, LD_BUG, SOCKS4_NETWORK_LEN, edge_connection_t::socks_request, socks_request_t::socks_version, stream_end_reason_to_socks5_response(), TO_CONN, and tor_assert.

Referenced by _connection_mark_unattached_ap(), connection_ap_handshake_process_socks(), connection_ap_handshake_socks_resolved(), and connection_edge_process_relay_cell_not_open().

void connection_ap_handshake_socks_resolved ( edge_connection_t conn,
int  answer_type,
size_t  answer_len,
const char *  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.

References socks_request_t::address, edge_connection_t::chosen_exit_name, client_dns_set_addressmap(), client_dns_set_reverse_addressmap(), connection_ap_handshake_socks_reply(), edge_connection_t::dns_server_request, dnsserv_resolved(), get_uint32(), socks_request_t::has_finished, edge_connection_t::is_dns_request, set_uint16(), SOCKS4_NETWORK_LEN, edge_connection_t::socks_request, socks_request_t::socks_version, tell_controller_about_resolved_result(), and tor_free.

Referenced by _connection_mark_unattached_ap(), and connection_edge_process_relay_cell_not_open().

edge_connection_t* connection_ap_make_link ( char *  address,
uint16_t  port,
const char *  digest,
int  use_begindir,
int  want_onehop 
)

static int connection_ap_process_natd ( edge_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.

References edge_connection_t::_base, socks_request_t::address, AP_CONN_STATE_CIRCUIT_WAIT, AP_CONN_STATE_CONTROLLER_WAIT, AP_CONN_STATE_NATD_WAIT, socks_request_t::command, CONN_TYPE_AP, connection_ap_handshake_rewrite_and_attach(), control_event_stream_status(), END_STREAM_REASON_INVALID_NATD_DEST, escaped(), fetch_from_buf_line(), get_options(), socks_request_t::has_finished, connection_t::inbuf, LD_APP, or_options_t::LeaveStreamsUnattached, socks_request_t::port, SOCKS_COMMAND_CONNECT, edge_connection_t::socks_request, connection_t::state, strcmpstart(), tor_assert, tor_parse_long(), and connection_t::type.

Referenced by connection_edge_process_inbuf().

int connection_ap_process_transparent ( edge_connection_t conn  ) 

int connection_edge_destroy ( circid_t  circ_id,
edge_connection_t conn 
)

int connection_edge_end ( edge_connection_t conn,
uint8_t  reason 
)

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.

References edge_connection_t::_base, connection_edge_end(), errno_to_stream_end_reason(), connection_t::s, and tor_assert.

Referenced by conn_read_callback(), connection_exit_connect(), connection_handle_read_impl(), and connection_handle_write_impl().

int connection_edge_finished_connecting ( edge_connection_t edge_conn  ) 

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.

References edge_connection_t::_base, AP_CONN_STATE_CIRCUIT_WAIT, AP_CONN_STATE_CONNECT_WAIT, AP_CONN_STATE_CONTROLLER_WAIT, AP_CONN_STATE_NATD_WAIT, AP_CONN_STATE_OPEN, AP_CONN_STATE_RENDDESC_WAIT, AP_CONN_STATE_SOCKS_WAIT, connection_edge_consider_sending_sendme(), connection_stop_writing(), EXIT_CONN_STATE_OPEN, LD_BUG, connection_t::state, TO_CONN, tor_assert, and tor_fragile_assert.

Referenced by connection_finished_flushing().

int connection_edge_is_rendezvous_stream ( edge_connection_t conn  ) 

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.

References edge_connection_t::_base, AP_CONN_STATE_CIRCUIT_WAIT, AP_CONN_STATE_CONNECT_WAIT, AP_CONN_STATE_CONTROLLER_WAIT, AP_CONN_STATE_NATD_WAIT, AP_CONN_STATE_OPEN, AP_CONN_STATE_RENDDESC_WAIT, AP_CONN_STATE_RESOLVE_WAIT, AP_CONN_STATE_SOCKS_WAIT, conn_state_to_string(), connection_ap_handshake_process_socks(), connection_ap_process_natd(), connection_edge_end(), connection_edge_package_raw_inbuf(), EXIT_CONN_STATE_CONNECTING, EXIT_CONN_STATE_OPEN, LD_BUG, LD_EDGE, connection_t::state, TO_CONN, tor_assert, tor_fragile_assert, and connection_t::type.

Referenced by connection_edge_finished_connecting(), and connection_process_inbuf().

int connection_edge_reached_eof ( edge_connection_t 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.

References edge_connection_t::_base, or_connection_t::_base, connection_t::addr, connection_t::address, assert_circuit_ok(), CIRCUIT_IS_ORIGIN, CIRCUIT_PURPOSE_OR, CIRCUIT_PURPOSE_S_REND_JOINED, relay_header_t::command, CONN_TYPE_EXIT, connection_edge_is_rendezvous_stream(), connection_exit_connect(), connection_exit_connect_dir(), connection_free(), connection_or_digest_is_known_relay(), origin_circuit_t::cpath, edge_connection_t::cpath_layer, edge_connection_t::deliver_window, directory_permits_begindir_requests(), circuit_t::dirreq_id, dns_resolve(), edge_connection_new(), EXIT_CONN_STATE_CONNECTING, EXIT_CONN_STATE_RESOLVEFAILED, EXIT_PURPOSE_CONNECT, get_options(), or_connection_t::identity_digest, or_circuit_t::is_first_hop, LD_BUG, LD_PROTOCOL, LD_REND, relay_header_t::length, edge_connection_t::next_stream, edge_connection_t::on_circuit, or_circuit_t::p_conn, origin_circuit_t::p_streams, edge_connection_t::package_window, parse_addr_port(), cell_t::payload, connection_t::port, crypt_path_t::prev, connection_t::purpose, circuit_t::purpose, or_connection_t::real_addr, RELAY_HEADER_SIZE, relay_header_unpack(), relay_send_end_cell_from_edge(), origin_circuit_t::rend_data, edge_connection_t::rend_data, rend_data_dup(), rend_service_set_connection_addr_port(), safe_str(), server_mode(), connection_t::state, edge_connection_t::stream_id, relay_header_t::stream_id, STREAMWINDOW_START, TO_CONN, TO_OR_CIRCUIT(), TO_ORIGIN_CIRCUIT(), tor_addr_copy(), tor_addr_is_null(), tor_assert, tor_dup_addr(), tor_free, tor_strlower(), and we_are_hibernating().

Referenced by connection_edge_process_relay_cell().

int connection_exit_begin_resolve ( cell_t cell,
or_circuit_t circ 
)

void connection_exit_connect ( edge_connection_t edge_conn  ) 

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.

References dir_connection_t::_base, edge_connection_t::_base, connection_t::addr, connection_t::address, CONN_TYPE_DIR, connection_add(), connection_close_immediate(), connection_edge_end(), connection_edge_send_command(), connection_free(), connection_link_connections(), connection_start_reading(), DIR_CONN_STATE_SERVER_COMMAND_WAIT, dir_connection_new(), DIR_PURPOSE_SERVER, EXIT_CONN_STATE_OPEN, or_circuit_t::n_streams, edge_connection_t::next_stream, edge_connection_t::on_circuit, connection_t::port, connection_t::purpose, connection_t::state, TO_CONN, TO_OR_CIRCUIT(), tor_addr_copy(), and connection_t::type.

Referenced by connection_exit_begin_conn().

static int consider_plaintext_ports ( edge_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.

References control_event_client_status(), get_options(), LD_APP, or_options_t::RejectPlaintextPorts, smartlist_string_num_isin(), and or_options_t::WarnPlaintextPorts.

Referenced by circuit_discard_optional_exit_enclaves().

static streamid_t get_unique_stream_id_by_circ ( origin_circuit_t circ  )  [static]

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.

References LD_APP, edge_connection_t::next_stream, origin_circuit_t::next_stream_id, origin_circuit_t::p_streams, and edge_connection_t::stream_id.

Referenced by connection_ap_handshake_send_begin(), and connection_ap_handshake_send_resolve().

hostname_type_t parse_extended_hostname ( char *  address,
int  allowdotexit 
)

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_HOSTNAME.

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

Otherwise: Return NORMAL_HOSTNAME and change nothing.

References LD_APP, REND_SERVICE_ID_LEN_BASE32, and rend_valid_service_id().

int parse_virtual_addr_network ( const char *  val,
int  validate_only,
char **  msg 
)

Read a netmask of the form 127.192.0.0/10 from "val", and check whether it's a valid set of virtual addresses to hand out in response to MAPADDRESS requests. Return 0 on success; set *msg (if provided) to a newly allocated string and return -1 on failure. If validate_only is false, sets the actual virtual address range to the parsed value.

References addr_mask_cmp_bits(), next_virtual_addr, parse_addr_and_port_range(), virtual_addr_netmask_bits, and virtual_addr_network.

Referenced by options_act().

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

References CIRCUIT_PURPOSE_IS_CLIENT, circuit_t::purpose, and relay_send_command_from_edge().

Referenced by connection_exit_begin_conn().

static void tell_controller_about_resolved_result ( edge_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().

References socks_request_t::address, control_event_address_mapped(), get_uint32(), INET_NTOA_BUF_LEN, edge_connection_t::socks_request, tor_free, and tor_inet_ntoa().

Referenced by connection_ap_handshake_socks_resolved().


Variable Documentation

strmap_t* addressmap = NULL [static]

uint32_t next_virtual_addr = 0x7fc00000u [static]

What's the next virtual address we will hand out?

Referenced by addressmap_get_virtual_address(), and parse_virtual_addr_network().

strmap_t* virtaddress_reversemap = NULL [static]

Table mapping addresses to which virtual address, if any, we assigned them to.

We maintain the following invariant: if [A,B] is in virtaddress_reversemap, then B must be a virtual address, and [A,B] must be in addressmap. We do not require that the converse hold: if it fails, then we could end up mapping two virtual addresses to the same address, which is no disaster.

Referenced by addressmap_free_all(), addressmap_init(), addressmap_register_virtual_address(), and addressmap_virtaddress_remove().

How many bits of virtual_addr_network are fixed?

Referenced by address_is_in_virtual_range(), addressmap_get_virtual_address(), and parse_virtual_addr_network().

uint32_t virtual_addr_network = 0x7fc00000u [static]

Which network should we use for virtual IPv4 addresses? Only the first bits of this value are fixed.

Referenced by address_is_in_virtual_range(), addressmap_get_virtual_address(), and parse_virtual_addr_network().


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