tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

connection_edge.h (14184B)


      1 /* Copyright (c) 2001 Matej Pfajfar.
      2 * Copyright (c) 2001-2004, Roger Dingledine.
      3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
      4 * Copyright (c) 2007-2021, The Tor Project, Inc. */
      5 /* See LICENSE for licensing information */
      6 
      7 /**
      8 * \file connection_edge.h
      9 * \brief Header file for connection_edge.c.
     10 **/
     11 
     12 #ifndef TOR_CONNECTION_EDGE_H
     13 #define TOR_CONNECTION_EDGE_H
     14 
     15 #include "core/or/relay_msg_st.h"
     16 
     17 #include "lib/testsupport/testsupport.h"
     18 #include "lib/encoding/confline.h"
     19 
     20 #include "feature/hs/hs_service.h"
     21 
     22 edge_connection_t *TO_EDGE_CONN(connection_t *);
     23 entry_connection_t *TO_ENTRY_CONN(connection_t *);
     24 entry_connection_t *EDGE_TO_ENTRY_CONN(edge_connection_t *);
     25 
     26 const edge_connection_t *CONST_TO_EDGE_CONN(const connection_t *);
     27 const entry_connection_t *CONST_TO_ENTRY_CONN(const connection_t *);
     28 const entry_connection_t *CONST_EDGE_TO_ENTRY_CONN(const edge_connection_t *);
     29 
     30 #define EXIT_CONN_STATE_MIN_ 1
     31 /** State for an exit connection: waiting for response from DNS farm. */
     32 #define EXIT_CONN_STATE_RESOLVING 1
     33 /** State for an exit connection: waiting for connect() to finish. */
     34 #define EXIT_CONN_STATE_CONNECTING 2
     35 /** State for an exit connection: open and ready to transmit data. */
     36 #define EXIT_CONN_STATE_OPEN 3
     37 /** State for an exit connection: waiting to be removed. */
     38 #define EXIT_CONN_STATE_RESOLVEFAILED 4
     39 #define EXIT_CONN_STATE_MAX_ 4
     40 
     41 /* The AP state values must be disjoint from the EXIT state values. */
     42 #define AP_CONN_STATE_MIN_ 5
     43 /** State for a SOCKS connection: waiting for SOCKS request. */
     44 #define AP_CONN_STATE_SOCKS_WAIT 5
     45 /** State for a SOCKS connection: got a y.onion URL; waiting to receive
     46 * rendezvous descriptor. */
     47 #define AP_CONN_STATE_RENDDESC_WAIT 6
     48 /** The controller will attach this connection to a circuit; it isn't our
     49 * job to do so. */
     50 #define AP_CONN_STATE_CONTROLLER_WAIT 7
     51 /** State for a SOCKS connection: waiting for a completed circuit. */
     52 #define AP_CONN_STATE_CIRCUIT_WAIT 8
     53 /** State for a SOCKS connection: sent BEGIN, waiting for CONNECTED. */
     54 #define AP_CONN_STATE_CONNECT_WAIT 9
     55 /** State for a SOCKS connection: sent RESOLVE, waiting for RESOLVED. */
     56 #define AP_CONN_STATE_RESOLVE_WAIT 10
     57 /** State for a SOCKS connection: ready to send and receive. */
     58 #define AP_CONN_STATE_OPEN 11
     59 /** State for a transparent natd connection: waiting for original
     60 * destination. */
     61 #define AP_CONN_STATE_NATD_WAIT 12
     62 /** State for an HTTP tunnel: waiting for an HTTP CONNECT command. */
     63 #define AP_CONN_STATE_HTTP_CONNECT_WAIT 13
     64 #define AP_CONN_STATE_MAX_ 13
     65 
     66 #define EXIT_PURPOSE_MIN_ 1
     67 /** This exit stream wants to do an ordinary connect. */
     68 #define EXIT_PURPOSE_CONNECT 1
     69 /** This exit stream wants to do a resolve (either normal or reverse). */
     70 #define EXIT_PURPOSE_RESOLVE 2
     71 #define EXIT_PURPOSE_MAX_ 2
     72 
     73 /** True iff the AP_CONN_STATE_* value <b>s</b> means that the corresponding
     74 * edge connection is not attached to any circuit. */
     75 #define AP_CONN_STATE_IS_UNATTACHED(s) \
     76  ((s) <= AP_CONN_STATE_CIRCUIT_WAIT || (s) == AP_CONN_STATE_NATD_WAIT)
     77 
     78 #define connection_mark_unattached_ap(conn, endreason)                  \
     79  connection_mark_unattached_ap_((conn), (endreason), __LINE__, SHORT_FILE__)
     80 
     81 /** Possible return values for parse_extended_hostname. */
     82 typedef enum hostname_type_t {
     83  BAD_HOSTNAME,
     84  EXIT_HOSTNAME,
     85  NORMAL_HOSTNAME,
     86  ONION_V3_HOSTNAME,
     87 } hostname_type_t;
     88 
     89 MOCK_DECL(void,connection_mark_unattached_ap_,
     90          (entry_connection_t *conn, int endreason,
     91           int line, const char *file));
     92 int connection_edge_reached_eof(edge_connection_t *conn);
     93 int connection_edge_process_inbuf(edge_connection_t *conn,
     94                                  int package_partial);
     95 int connection_edge_destroy(circid_t circ_id, edge_connection_t *conn);
     96 int connection_edge_end(edge_connection_t *conn, uint8_t reason);
     97 int connection_edge_end_errno(edge_connection_t *conn);
     98 void connection_edge_end_close(edge_connection_t *conn, uint8_t reason);
     99 int connection_edge_flushed_some(edge_connection_t *conn);
    100 int connection_edge_finished_flushing(edge_connection_t *conn);
    101 int connection_edge_finished_connecting(edge_connection_t *conn);
    102 
    103 void connection_entry_set_controller_wait(entry_connection_t *conn);
    104 
    105 void connection_ap_about_to_close(entry_connection_t *edge_conn);
    106 void connection_exit_about_to_close(edge_connection_t *edge_conn);
    107 void connection_reapply_exit_policy(config_line_t *changes);
    108 
    109 MOCK_DECL(int,
    110          connection_ap_handshake_send_begin,(entry_connection_t *ap_conn));
    111 int connection_ap_handshake_send_resolve(entry_connection_t *ap_conn);
    112 
    113 entry_connection_t  *connection_ap_make_link(connection_t *partner,
    114                                            char *address, uint16_t port,
    115                                            const char *digest,
    116                                            int session_group,
    117                                            int isolation_flags,
    118                                            int use_begindir, int want_onehop);
    119 void connection_ap_handshake_socks_reply(entry_connection_t *conn, char *reply,
    120                                         size_t replylen,
    121                                         int endreason);
    122 MOCK_DECL(void,connection_ap_handshake_socks_resolved,
    123          (entry_connection_t *conn,
    124           int answer_type,
    125           size_t answer_len,
    126           const uint8_t *answer,
    127           int ttl,
    128           time_t expires));
    129 void connection_ap_handshake_socks_resolved_addr(entry_connection_t *conn,
    130                                                 const tor_addr_t *answer,
    131                                                 int ttl,
    132                                                 time_t expires);
    133 
    134 int connection_exit_begin_conn(const relay_msg_t *msg, circuit_t *circ);
    135 int connection_exit_begin_resolve(const relay_msg_t *msg, or_circuit_t *circ);
    136 void connection_exit_connect(edge_connection_t *conn);
    137 int connection_edge_is_rendezvous_stream(const edge_connection_t *conn);
    138 int connection_ap_can_use_exit(const entry_connection_t *conn,
    139                               const node_t *exit);
    140 void connection_ap_expire_beginning(void);
    141 void connection_ap_rescan_and_attach_pending(void);
    142 void connection_ap_attach_pending(int retry);
    143 void connection_ap_mark_as_pending_circuit_(entry_connection_t *entry_conn,
    144                                           const char *file, int line);
    145 #define connection_ap_mark_as_pending_circuit(c) \
    146  connection_ap_mark_as_pending_circuit_((c), __FILE__, __LINE__)
    147 void connection_ap_mark_as_non_pending_circuit(entry_connection_t *entry_conn);
    148 void connection_ap_mark_as_waiting_for_renddesc(
    149                                       entry_connection_t *entry_conn);
    150 
    151 #define CONNECTION_AP_EXPECT_NONPENDING(c) do {                         \
    152    if (ENTRY_TO_CONN(c)->state == AP_CONN_STATE_CIRCUIT_WAIT) {        \
    153      log_warn(LD_BUG, "At %s:%d: %p was unexpectedly in circuit_wait.", \
    154               __FILE__, __LINE__, (c));                                \
    155      connection_ap_mark_as_non_pending_circuit(c);                     \
    156    }                                                                   \
    157  } while (0)
    158 void connection_ap_fail_onehop(const char *failed_digest,
    159                               cpath_build_state_t *build_state);
    160 void circuit_discard_optional_exit_enclaves(extend_info_t *info);
    161 int connection_ap_detach_retriable(entry_connection_t *conn,
    162                                   origin_circuit_t *circ,
    163                                   int reason);
    164 int connection_ap_process_transparent(entry_connection_t *conn);
    165 
    166 int address_is_invalid_destination(const char *address, int client);
    167 
    168 MOCK_DECL(int, connection_ap_rewrite_and_attach_if_allowed,
    169                                                (entry_connection_t *conn,
    170                                                 origin_circuit_t *circ,
    171                                                 crypt_path_t *cpath));
    172 int connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn,
    173                                               origin_circuit_t *circ,
    174                                               crypt_path_t *cpath);
    175 
    176 #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
    177 int get_pf_socket(void);
    178 #endif
    179 
    180 int connection_edge_compatible_with_circuit(const entry_connection_t *conn,
    181                                            const origin_circuit_t *circ);
    182 int connection_edge_update_circuit_isolation(const entry_connection_t *conn,
    183                                             origin_circuit_t *circ,
    184                                             int dry_run);
    185 void circuit_clear_isolation(origin_circuit_t *circ);
    186 streamid_t get_unique_stream_id_by_circ(origin_circuit_t *circ);
    187 
    188 void connection_edge_free_all(void);
    189 
    190 void connection_ap_warn_and_unmark_if_pending_circ(
    191                                             entry_connection_t *entry_conn,
    192                                             const char *where);
    193 
    194 /** Lowest value for DNS ttl clipping excluding the random addition. */
    195 #define MIN_DNS_TTL (5*60)
    196 /** Highest value for DNS ttl clipping excluding the random addition. */
    197 #define MAX_DNS_TTL (60*60)
    198 /** How long do we keep DNS cache entries before purging them (regardless of
    199 * their TTL)? */
    200 #define MAX_DNS_ENTRY_AGE (3*60*60)
    201 /** How long do we cache/tell clients to cache DNS records when no TTL is
    202 * known? */
    203 #define DEFAULT_DNS_TTL (30*60)
    204 /** How much should we +- each TTL to make it fuzzy with uniform sampling at
    205 * exits?  The value 4 minutes was chosen so that the lowest possible clip is
    206 * 60s.  Such low clips were used in the past for all TTLs due to a bug in Tor,
    207 * see "The effect of DNS on Tor's Anonymity" by Greschbach et al.  In other
    208 * words, sampling such low clips is unlikely to cause any breakage at exits.
    209 */
    210 #define FUZZY_DNS_TTL (4*60)
    211 
    212 uint32_t clip_dns_ttl(uint32_t ttl);
    213 uint32_t clip_dns_fuzzy_ttl(uint32_t ttl);
    214 
    215 int connection_half_edge_is_valid_data(const smartlist_t *half_conns,
    216                                       streamid_t stream_id);
    217 int connection_half_edge_is_valid_sendme(const smartlist_t *half_conns,
    218                                         streamid_t stream_id);
    219 int connection_half_edge_is_valid_connected(const smartlist_t *half_conns,
    220                                            streamid_t stream_id);
    221 int connection_half_edge_is_valid_end(smartlist_t *half_conns,
    222                                      streamid_t stream_id);
    223 int connection_half_edge_is_valid_resolved(smartlist_t *half_conns,
    224                                           streamid_t stream_id);
    225 bool connection_half_edges_waiting(const origin_circuit_t *circ);
    226 
    227 size_t half_streams_get_total_allocation(void);
    228 struct half_edge_t;
    229 void half_edge_free_(struct half_edge_t *he);
    230 #define half_edge_free(he) \
    231  FREE_AND_NULL(half_edge_t, half_edge_free_, (he))
    232 
    233 /** @name Begin-cell flags
    234 *
    235 * These flags are used in RELAY_BEGIN cells to change the default behavior
    236 * of the cell.
    237 *
    238 * @{
    239 **/
    240 /** When this flag is set, the client is willing to get connected to IPv6
    241 * addresses */
    242 #define BEGIN_FLAG_IPV6_OK        (1u<<0)
    243 /** When this flag is set, the client DOES NOT support connecting to IPv4
    244 * addresses.  (The sense of this flag is inverted from IPV6_OK, so that the
    245 * old default behavior of Tor is equivalent to having all flags set to 0.)
    246 **/
    247 #define BEGIN_FLAG_IPV4_NOT_OK    (1u<<1)
    248 /** When this flag is set, if we find both an IPv4 and an IPv6 address,
    249 * we use the IPv6 address.  Otherwise we use the IPv4 address. */
    250 #define BEGIN_FLAG_IPV6_PREFERRED (1u<<2)
    251 /**@}*/
    252 
    253 #ifdef CONNECTION_EDGE_PRIVATE
    254 
    255 STATIC bool parse_extended_hostname(char *address, hostname_type_t *type_out);
    256 
    257 /** A parsed BEGIN or BEGIN_DIR cell */
    258 typedef struct begin_cell_t {
    259  /** The address the client has asked us to connect to, or NULL if this is
    260   * a BEGIN_DIR cell*/
    261  char *address;
    262  /** The flags specified in the BEGIN cell's body.  One or more of
    263   * BEGIN_FLAG_*. */
    264  uint32_t flags;
    265  /** The client's requested port. */
    266  uint16_t port;
    267  /** The client's requested Stream ID */
    268  uint16_t stream_id;
    269  /** True iff this is a BEGIN_DIR cell. */
    270  unsigned is_begindir : 1;
    271 } begin_cell_t;
    272 
    273 STATIC int begin_cell_parse(const relay_msg_t *msg, begin_cell_t *bcell,
    274                            uint8_t *end_reason_out);
    275 STATIC int connected_cell_format_payload(uint8_t *payload_out,
    276                                  const tor_addr_t *addr,
    277                                  uint32_t ttl);
    278 
    279 typedef struct {
    280  /** Original address, after we lowercased it but before we started
    281   * mapping it.
    282   */
    283  char orig_address[MAX_SOCKS_ADDR_LEN];
    284  /** True iff the address has been automatically remapped to a local
    285   * address in VirtualAddrNetwork.  (Only set true when we do a resolve
    286   * and get a virtual address; not when we connect to the address.) */
    287  int automap;
    288  /** If this connection has a .exit address, who put it there? */
    289  addressmap_entry_source_t exit_source;
    290  /** If we've rewritten the address, when does this map expire? */
    291  time_t map_expires;
    292  /** If we should close the connection, this is the end_reason to pass
    293   * to connection_mark_unattached_ap */
    294  int end_reason;
    295  /** True iff we should close the connection, either because of error or
    296   * because of successful early RESOLVED reply. */
    297  int should_close;
    298 } rewrite_result_t;
    299 
    300 STATIC void connection_ap_handshake_rewrite(entry_connection_t *conn,
    301                                            rewrite_result_t *out);
    302 
    303 STATIC int connection_ap_process_http_connect(entry_connection_t *conn);
    304 STATIC void export_hs_client_circuit_id(edge_connection_t *edge_conn,
    305                            hs_circuit_id_protocol_t protocol);
    306 
    307 struct half_edge_t;
    308 STATIC void connection_half_edge_add(const edge_connection_t *conn,
    309                                     origin_circuit_t *circ);
    310 STATIC struct half_edge_t *connection_half_edge_find_stream_id(
    311                                     const smartlist_t *half_conns,
    312                                     streamid_t stream_id);
    313 STATIC bool using_old_proxy_auth(const char *auth);
    314 #endif /* defined(CONNECTION_EDGE_PRIVATE) */
    315 
    316 #endif /* !defined(TOR_CONNECTION_EDGE_H) */