Tor源码文件分析 — Connetion_Edge

  所谓的Edge连接主要是形容在链路两端所使用的连接,包括AP连接与EXIT连接两种。Edge连接的存在,主要是为了个应用程序连接提供服务,所以才将两种Edge连接命名为Application Proxy应用代理连接和EXIT出口连接。这两种连接主要出现于链路两端,即链路第一跳与链路最后一跳,分别用于接受应用请求和处理应用请求的发出。因为Edge连接在Tor系统中也具有重要的作用,所以本篇就简单分析关于Edge连接的源码文件connection_edge.c。

  因为Edge连接位于链路两端,需要处理的事务比中间结点单纯的传递和记录要繁琐出许多,有很多部分笔者也没有很详细的看过或找出其应用需要,此处必定有很多讲的含糊其辞和不准确的地方,请大家包涵。

0. 全局变量

/** A client-side struct to remember requests to rewrite addresses
 * to new addresses. These structs are stored in the hash table
 * "addressmap" below.
 * 由此处可见,addressmap全局变量的使用,只存在于客户端,其他身份的TOR成员并不使用此全局变量;
 *
 * There are 5 ways to set an address mapping:
 * - A MapAddress command from the controller [permanent]
 * - An AddressMap directive in the torrc [permanent]
 * - When a TrackHostExits torrc directive is triggered [temporary]
 * - When a DNS resolve succeeds [temporary]
 * - When a DNS resolve fails [temporary]
 * 由此处可见,除去在配置文件中进行地址映射之外,主要还是靠DNS解析来修改address mapping;
 *
 * When an addressmap request is made but one is already registered,
 * the new one is replaced only if the currently registered one has
 * no "new_address" (that is, it's in the process of DNS resolve),
 * or if the new one is permanent (expires==0 or 1).
 *
 * (We overload the 'expires' field, using "0" for mappings set via
 * the configuration file, "1" for mappings set from the control
 * interface, and other values for DNS and TrackHostExit mappings that can
 * expire.)
 *
 * A mapping may be 'wildcarded'.  If "src_wildcard" is true, then
 * any address that ends with a . followed by the key for this entry will
 * get remapped by it.  If "dst_wildcard" is also true, then only the
 * matching suffix of such addresses will get replaced by new_address.
 */
typedef struct {
  char *new_address;
  time_t expires;
  addressmap_entry_source_t source:3;
  unsigned src_wildcard:1;
  unsigned dst_wildcard:1;
  short num_resolve_failures;
} addressmap_entry_t;

/** Entry for mapping addresses to which virtual address we mapped them to. */
typedef struct {
  char *ipv4_address;
  char *hostname_address;
} virtaddress_entry_t;

/** A hash table to store client-side address rewrite instructions. */
static strmap_t *addressmap=NULL;

/**
 * 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.
 **/
static strmap_t *virtaddress_reversemap=NULL;

  此处两全局变量的作用尚不明确,有待分析。

/* By default, we hand out 127.192.0.1 through 127.254.254.254.
 * These addresses should map to localhost, so even if the
 * application accidentally tried to connect to them directly (not
 * via Tor), it wouldn't get too far astray.
 *
 * These options are configured by parse_virtual_addr_network().
 */
/** Which network should we use for virtual IPv4 addresses?  Only the first
 * bits of this value are fixed. */
static uint32_t virtual_addr_network = 0x7fc00000u;
/** How many bits of virtual_addr_network are fixed? */
static maskbits_t virtual_addr_netmask_bits = 10;
/** What's the next virtual address we will hand out? */
static uint32_t next_virtual_addr    = 0x7fc00000u;

  此处三全局变量的作用尚不明确,有待分析。

1. AP与EXIT通用函数

  connection_edge_reached_eof  –>  connection_edge_end

  断开连接,如果身份正确(AP)则发送end cell通知对应出口结点关闭数据流;

  connection_edge_process_inbuf

  分情况管理连接事务及连接缓冲区内部的数据;

  connection_edge_destroy  –>  connection_mark_unattached_ap(若身份为AP)

  connection_edge_end_errno  –> connection_edge_end

  连接因链路断开而结束或因某个errno而结束,则关闭连接,发送流终止通知;

  connection_edge_flushed_some

  connection_edge_finished_flushing

  connection_edge_finished_connecting(主要用于身份为EXIT的情况)

  连接完成缓冲区输出或完成下层连接之时调用相关函数,以完成扫尾工作;

  connection_edge_is_rendezvous_stream

  connection_edge_compatible_with_circuit

  connection_edge_update_circuit_isolation

  circuit_clear_isolation

  连接的某些属性判断,关键点在于rendezvous子系统和isolation flag作用;

2. AP处理函数

  connection_mark_unattached_ap

  connection_ap_about_to_close

  AP连接关闭前的处理以及关闭处理;

  connection_ap_handshake_send_begin

  connection_ap_handshake_send_resolve

  AP连接向远端发送Relay Begin以及Relay Resolve命令,用于完成开启流与地址解析的功能;

  connection_ap_make_link

  一般用于内部DIR连接与AP连接相关联之时,该函数创建一个可用的AP连接,并将其与DIR连接互联;可用意味着AP连接找到附着的链路Circuit;

  connection_ap_handshake_socks_reply

  connection_ap_handshake_socks_resolved

  向AP连接送回相关消息:连接结束消息,地址解析成功消息;

  connection_ap_can_use_exit

  判断出口结点是否允许相应AP连接出口;

  connection_ap_expire_beginning

  connection_ap_attach_pending

  connection_ap_detach_retriable

  重连一个请求超时的AP连接;重新为找不到链路的AP连接分配链路;

  connection_ap_fail_onehop

  通知所有等待某个无法连接的结点的AP连接;

  connection_ap_process_transparent  –>  connection_ap_rewrite_and_attach_if_allowed  –>  connection_ap_handshake_rewrite_and_attach

  透明AP使用的函数,未细究;

  

3. EXIT处理函数

  connection_exit_about_to_close

  connection_exit_begin_conn  –>  connection_exit_connect

  connection_exit_begin_resolve

  以上四个函数包括了EXIT连接的几乎所有操作,主要就是连接的建立与对外的连接,以及地址解析和关闭;

4. AddressMap相关处理函数(暂略)

  address_is_invalid_destination

  parse_virtual_addr_network

  parse_extended_hostname

  addressmap_init

  addressmap_clear_excluded_trackexithosts

  addressmap_clear_invalid_automaps

  addressmap_clean

  addressmap_clear_configured

  addressmap_clear_transient

  addressmap_free_all

  addressmap_rewrite

  addressmap_have_mapping

  addressmap_register

  addressmap_register_virtual_address

  addressmap_get_mappings

  client_dns_incr_failures

  client_dns_clear_failures

  client_dns_set_addressmap

5. 额外函数(暂略)

  circuit_discard_optional_exit_enclaves

  get_pf_socket