#include "or.h"
#include <linux/types.h>
#include <linux/netfilter_ipv4.h>
#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?
void _connection_mark_unattached_ap | ( | edge_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.
References edge_connection_t::_base, _connection_mark_for_close(), socks_request_t::command, CONN_TYPE_AP, connection_ap_handshake_socks_reply(), connection_ap_handshake_socks_resolved(), edge_connection_t::edge_has_sent_end, edge_connection_t::end_reason, END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED, socks_request_t::has_finished, connection_t::hold_open_until_flushed, LD_BUG, connection_t::marked_for_close, edge_connection_t::socks_request, TO_CONN, tor_assert, and connection_t::type.
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] |
Free storage held by a virtaddress_entry_t* entry in ent.
References address_is_in_virtual_range(), virtaddress_entry_t::hostname_address, virtaddress_entry_t::ipv4_address, addressmap_entry_t::new_address, strmap_get(), strmap_remove(), tor_free, and virtaddress_reversemap.
Referenced by addressmap_ent_remove(), and addressmap_register().
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.
References socks_request_t::address, AP_CONN_STATE_CIRCUIT_WAIT, edge_connection_t::chosen_exit_name, edge_connection_t::chosen_exit_optional, edge_connection_t::chosen_exit_retries, clear_trackexithost_mappings(), CONN_TYPE_AP, consider_plaintext_ports(), escaped_safe_str_client(), get_connection_array(), LD_APP, extend_info_t::nickname, socks_request_t::port, router_get_by_nickname(), safe_str_client(), edge_connection_t::socks_request, TO_EDGE_CONN(), tor_assert, and tor_free.
Referenced by circuit_build_failed().
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 | ) |
Tell any AP streams that are waiting for a new circuit to try again, either attaching to an available circ or launching a new one.
References edge_connection_t::_base, AP_CONN_STATE_CIRCUIT_WAIT, CONN_TYPE_AP, connection_ap_handshake_attach_circuit(), END_STREAM_REASON_CANT_ATTACH, get_connection_array(), connection_t::marked_for_close, and TO_EDGE_CONN().
Referenced by circuit_build_needed_circs(), circuit_has_opened(), rend_client_introcirc_has_opened(), rend_client_receive_rendezvous(), and rend_client_rendezvous_acked().
int connection_ap_can_use_exit | ( | edge_connection_t * | conn, | |
routerinfo_t * | exit, | |||
int | excluded_means_no | |||
) |
Return 1 if router exit 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.)
If excluded_means_no is 1 and Exclude*Nodes is set and excludes this relay, return 0.
References edge_connection_t::_base, or_options_t::_ExcludeExitNodesUnion, ADDR_POLICY_PROBABLY_REJECTED, ADDR_POLICY_REJECTED, socks_request_t::address, routerinfo_t::cache_info, edge_connection_t::chosen_exit_name, socks_request_t::command, compare_addr_to_addr_policy(), CONN_TYPE_AP, DIGEST_LEN, routerinfo_t::exit_policy, get_options(), routerinfo_t::has_old_dnsworkers, signed_descriptor_t::identity_digest, policy_is_reject_star(), socks_request_t::port, router_get_by_nickname(), routerset_contains_router(), SOCKS_COMMAND_CONNECT, SOCKS_COMMAND_RESOLVE_PTR, edge_connection_t::socks_request, or_options_t::StrictNodes, tor_assert, tor_inet_aton(), connection_t::type, and edge_connection_t::use_begindir.
Referenced by choose_good_exit_server_general(), circuit_get_open_circ_or_launch(), circuit_is_acceptable(), circuit_stream_is_being_handled(), and connection_ap_handshake_attach_circuit().
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 | ) |
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).
References edge_connection_t::_base, connection_t::addr, socks_request_t::address, AP_CONN_STATE_IS_UNATTACHED, AP_CONN_STATE_OPEN, circuit_get_by_edge_conn(), CIRCUIT_PURPOSE_C_GENERAL, CIRCUIT_PURPOSE_C_REND_JOINED, compute_retry_timeout(), conn_state_to_string(), CONN_TYPE_AP, connection_ap_detach_retriable(), connection_edge_end(), edge_connection_t::cpath_layer, edge_connection_t::edge_has_sent_end, edge_connection_t::end_reason, END_STREAM_REASON_CANT_ATTACH, crypt_path_t::extend_info, get_connection_array(), get_options(), LD_APP, LD_REND, connection_t::marked_for_close, or_options_t::MaxCircuitDirtiness, extend_info_t::nickname, edge_connection_t::num_socks_retries, socks_request_t::port, connection_t::port, circuit_t::purpose, safe_str_client(), edge_connection_t::socks_request, or_options_t::SocksTimeout, connection_t::state, connection_t::timestamp_created, circuit_t::timestamp_dirty, connection_t::timestamp_lastread, TO_EDGE_CONN(), TO_ORIGIN_CIRCUIT(), tor_addr_is_null(), and tor_assert.
Referenced by run_scheduled_events().
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.
References extend_info_t::addr, socks_request_t::address, AP_CONN_STATE_CIRCUIT_WAIT, cpath_build_state_t::chosen_exit, edge_connection_t::chosen_exit_name, CONN_TYPE_AP, DIGEST_LEN, get_connection_array(), hexdigest_to_digest(), LD_APP, socks_request_t::port, extend_info_t::port, edge_connection_t::socks_request, TO_EDGE_CONN(), tor_addr_eq, tor_addr_from_str(), tor_digest_is_zero(), and edge_connection_t::want_onehop.
Referenced by circuit_build_failed().
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] |
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.
References edge_connection_t::_base, AP_CONN_STATE_CONTROLLER_WAIT, AP_CONN_STATE_SOCKS_WAIT, socks_request_t::command, CONN_TYPE_AP, connection_ap_handshake_rewrite_and_attach(), connection_ap_handshake_socks_reply(), control_event_stream_status(), END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED, END_STREAM_REASON_SOCKSPROTOCOL, fetch_from_buf_socks(), get_options(), connection_t::inbuf, LD_APP, or_options_t::LeaveStreamsUnattached, socks_request_t::reply, socks_request_t::replylen, or_options_t::SafeSocks, edge_connection_t::socks_request, connection_t::state, or_options_t::TestSocks, TO_CONN, tor_assert, and connection_t::type.
Referenced by connection_edge_process_inbuf().
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 | ) |
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.
References origin_circuit_t::_base, edge_connection_t::_base, socks_request_t::address, AP_CONN_STATE_CIRCUIT_WAIT, AP_CONN_STATE_CONNECT_WAIT, origin_circuit_t::build_state, CELL_PAYLOAD_SIZE, CIRCUIT_PURPOSE_C_GENERAL, socks_request_t::command, CONN_TYPE_AP, connection_edge_send_command(), control_event_stream_status(), edge_connection_t::deliver_window, get_unique_stream_id_by_circ(), LD_APP, circuit_t::n_circ_id, edge_connection_t::on_circuit, cpath_build_state_t::onehop_tunnel, edge_connection_t::package_window, socks_request_t::port, circuit_t::purpose, RELAY_PAYLOAD_SIZE, connection_t::s, edge_connection_t::socks_request, connection_t::state, edge_connection_t::stream_id, STREAMWINDOW_START, TO_CIRCUIT, TO_ORIGIN_CIRCUIT(), tor_assert, tor_snprintf(), connection_t::type, and edge_connection_t::use_begindir.
Referenced by connection_ap_handshake_attach_chosen_circuit(), and connection_ap_handshake_attach_circuit().
int connection_ap_handshake_send_resolve | ( | edge_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.
References origin_circuit_t::_base, edge_connection_t::_base, connection_t::address, socks_request_t::address, AP_CONN_STATE_CIRCUIT_WAIT, AP_CONN_STATE_RESOLVE_WAIT, CIRCUIT_PURPOSE_C_GENERAL, socks_request_t::command, CONN_TYPE_AP, connection_edge_send_command(), control_event_stream_status(), get_unique_stream_id_by_circ(), LD_APP, LD_BUG, circuit_t::n_circ_id, edge_connection_t::on_circuit, circuit_t::purpose, REVERSE_LOOKUP_NAME_BUF_LEN, connection_t::s, safe_str_client(), SOCKS_COMMAND_RESOLVE, edge_connection_t::socks_request, connection_t::state, edge_connection_t::stream_id, TO_CIRCUIT, TO_ORIGIN_CIRCUIT(), tor_addr_parse_reverse_lookup_name(), tor_addr_to_reverse_lookup_name(), tor_assert, tor_free, and connection_t::type.
Referenced by connection_ap_handshake_attach_chosen_circuit().
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 | |||
) |
Make an AP connection_t, 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 other end of the linked connection pair, or -1 if error.
References edge_connection_t::_base, connection_t::addr, connection_t::address, socks_request_t::address, AP_CONN_STATE_CIRCUIT_WAIT, base16_encode(), edge_connection_t::chosen_exit_name, socks_request_t::command, CONN_TYPE_AP, connection_add(), connection_ap_handshake_attach_circuit(), connection_free(), control_event_stream_status(), DIGEST_LEN, edge_connection_new(), END_STREAM_REASON_CANT_ATTACH, socks_request_t::has_finished, HEX_DIGEST_LEN, LD_APP, connection_t::linked, connection_t::marked_for_close, connection_t::port, socks_request_t::port, safe_str_client(), SOCKS_COMMAND_CONNECT, edge_connection_t::socks_request, socks_request_t::socks_version, connection_t::state, TO_CONN, tor_addr_make_unspec(), tor_assert, edge_connection_t::use_begindir, and edge_connection_t::want_onehop.
Referenced by directory_initiate_command_rend().
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 | ) |
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.
References edge_connection_t::_base, AP_CONN_STATE_CONTROLLER_WAIT, socks_request_t::command, CONN_TYPE_AP, connection_ap_get_original_destination(), connection_ap_handshake_rewrite_and_attach(), control_event_stream_status(), END_STREAM_REASON_CANT_FETCH_ORIG_DEST, get_options(), socks_request_t::has_finished, LD_APP, or_options_t::LeaveStreamsUnattached, SOCKS_COMMAND_CONNECT, edge_connection_t::socks_request, connection_t::state, tor_assert, and connection_t::type.
Referenced by connection_init_accepted_conn().
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.
References edge_connection_t::_base, CONN_TYPE_AP, control_event_stream_bandwidth(), control_event_stream_status(), edge_connection_t::cpath_layer, edge_connection_t::edge_has_sent_end, edge_connection_t::end_reason, END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED, connection_t::hold_open_until_flushed, LD_EDGE, connection_t::marked_for_close, edge_connection_t::on_circuit, TO_CONN, and connection_t::type.
Referenced by _circuit_mark_for_close().
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.
References edge_connection_t::_base, connection_t::addr, edge_connection_t::address_ttl, circuit_get_by_edge_conn(), CIRCUIT_PURPOSE_IS_CLIENT, connection_edge_is_rendezvous_stream(), connection_edge_send_command(), dns_clip_ttl(), edge_connection_t::edge_has_sent_end, edge_connection_t::end_reason, LD_BUG, LD_EDGE, circuit_t::marked_for_close, connection_t::marked_for_close, connection_t::marked_for_close_file, circuit_t::purpose, RELAY_PAYLOAD_SIZE, connection_t::s, set_uint32(), tor_addr_family(), tor_addr_to_ipv4n(), and tor_fragile_assert.
Referenced by connection_ap_expire_beginning(), connection_edge_end_errno(), connection_edge_process_inbuf(), connection_edge_process_relay_cell(), connection_edge_process_relay_cell_not_open(), connection_edge_reached_eof(), connection_exit_connect(), connection_exit_connect_dir(), dns_cancel_pending_resolve(), dns_found_answer(), handle_control_attachstream(), hibernate_go_dormant(), and purge_expired_resolves().
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 | ) |
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.
References edge_connection_t::_base, connection_t::addr, connection_t::address, edge_connection_t::address_ttl, CONN_TYPE_EXIT, connection_edge_is_rendezvous_stream(), connection_edge_process_inbuf(), connection_edge_send_command(), connection_start_writing(), connection_wants_to_flush(), connection_watch_events(), dns_clip_ttl(), escaped_safe_str(), EXIT_CONN_STATE_CONNECTING, EXIT_CONN_STATE_OPEN, fmt_addr(), edge_connection_t::package_window, connection_t::port, rep_hist_note_exit_stream_opened(), safe_str(), set_uint32(), connection_t::state, TO_CONN, tor_addr_family(), tor_addr_to_ipv4n(), tor_assert, and connection_t::type.
Referenced by connection_finished_connecting().
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 | ) |
Return 1 if conn is a rendezvous stream, or 0 if it is a general stream.
References edge_connection_t::rend_data, and tor_assert.
Referenced by ap_stream_wants_exit_attention(), circuit_get_open_circ_or_launch(), connection_ap_handshake_attach_circuit(), connection_ap_process_end_not_open(), connection_edge_end(), connection_edge_finished_connecting(), connection_exit_begin_conn(), connection_exit_connect(), relay_lookup_conn(), and write_stream_target_to_buf().
int connection_edge_process_inbuf | ( | edge_connection_t * | conn, | |
int | package_partial | |||
) |
Handle new bytes on conn->inbuf based on state:
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 | ) |
There was an EOF. Send an end and mark the connection for close.
References edge_connection_t::_base, buf_datalen(), connection_edge_end(), connection_state_is_open(), socks_request_t::has_finished, connection_t::inbuf, LD_EDGE, connection_t::marked_for_close, connection_t::s, edge_connection_t::socks_request, and TO_CONN.
Referenced by connection_reached_eof().
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 | |||
) |
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.
References edge_connection_t::_base, connection_t::address, assert_circuit_ok(), CONN_TYPE_EXIT, connection_free(), dns_resolve(), edge_connection_new(), EXIT_CONN_STATE_RESOLVEFAILED, EXIT_PURPOSE_RESOLVE, relay_header_t::length, connection_t::marked_for_close, edge_connection_t::on_circuit, cell_t::payload, connection_t::port, connection_t::purpose, RELAY_HEADER_SIZE, relay_header_unpack(), connection_t::state, relay_header_t::stream_id, edge_connection_t::stream_id, TO_CIRCUIT, and TO_CONN.
Referenced by connection_edge_process_relay_cell().
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.)
References connection_t::addr, connection_t::address, edge_connection_t::address_ttl, circuit_detach_stream(), circuit_get_by_edge_conn(), connection_connect(), connection_edge_end(), connection_edge_end_errno(), connection_edge_is_rendezvous_stream(), connection_edge_send_command(), connection_free(), connection_wants_to_flush(), connection_watch_events(), dns_clip_ttl(), escaped_safe_str_client(), EXIT_CONN_STATE_CONNECTING, EXIT_CONN_STATE_OPEN, LD_BUG, connection_t::port, router_compare_to_my_exit_policy(), set_uint32(), connection_t::state, TO_CONN, tor_addr_family(), and tor_addr_to_ipv4n().
Referenced by connection_exit_begin_conn(), and dns_found_answer().
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().
strmap_t* addressmap = NULL [static] |
A hash table to store client-side address rewrite instructions.
Referenced by addressmap_free_all(), addressmap_get_mappings(), addressmap_get_virtual_address(), addressmap_have_mapping(), addressmap_init(), addressmap_register(), addressmap_register_virtual_address(), addressmap_rewrite(), addressmap_rewrite_reverse(), clear_trackexithost_mappings(), client_dns_clear_failures(), and client_dns_incr_failures().
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().
maskbits_t virtual_addr_netmask_bits = 10 [static] |
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().