Tor源码文件分析 — Connection

  Tor协议的层次结果经过简要分析可以大致概括为如下框图:

                DIR连接……            应用层

              ------------------------

                AP连接,EXIT连接……

              ------------------

                Circuit链路……           Tor协议层

              ------------------

                OR连接……          

              ------------------------

                TLS连接              传输层

  而其中的DIR,AP,EXIT,OR等连接均是对理解Tor协议非常重要的部分,所以有必要简要的介绍一下通用连接的源码文件connection.c。

0. 全局变量

// 用于检测IP地址变化的全局变量,引用处极少
// 该部分的全局变量只用于函数 client_check_address_changed
/** The last addresses that our network interface seemed to have been
 * binding to.  We use this as one way to detect when our IP changes.
 *
 * XXX024 We should really use the entire list of interfaces here.
 **/
static tor_addr_t *last_interface_ipv4 = NULL;
/* DOCDOC last_interface_ipv6 */
static tor_addr_t *last_interface_ipv6 = NULL;
/** A list of tor_addr_t for addresses we've used in outgoing connections.
 * Used to detect IP address changes. */
static smartlist_t *outgoing_addrs = NULL;

// 系统写令牌桶为空的指示全局变量
// 该全局变量的赋值处于函数 refill_callback
/** Did either global write bucket run dry last second? If so,
 * we are likely to run dry again this second, so be stingy with the
 * tokens we just put in. */
static int write_buckets_empty_last_second = 0;

1. 连接调试函数

  conn_type_to_string

  conn_state_to_string

  将连接类型与状态转换成易读的字符串形式;

  connection_dump_buffer_mem_stats

  将所有连接所使用的buffer情况输出;

2. 连接的新建与删除

              dir_connection_new

              or_connection_new

              edge_connection_new

  connection_new    –>      entry_connection_new        –>        connection_init

              control_connection_new

              listener_connection_new

  新建连接,并根据不同连接类型来初始化相应的连接;

  connection_free    <-    connection_unlink

  connection_free_all

  connection_about_to_close_connection

  connection_close_immediate

  connection_mark_for_close

  connection_mark_and_flush

  将连接进行关闭标记,关闭前处理或者直接关闭;

3. 连接的管理

  connection_expire_held_open

  将15秒内没有操作的连接关闭断开等待功能;(断开等待功能是指在连接被标记关闭时,只有其数据全部输出完毕时才进行关闭)

  connection_mark_all_noncontrol_listeners

  connection_mark_all_noncontrol_connections

  根据连接的属性,标记所有非控制的连接或监听连接;

  connection_get_by_global_id

  connection_get_by_type

  connection_get_by_type_purpose

  connection_get_by_type_addr_port_purpose

  connection_get_by_type_state

  connection_get_by_type_state_rendquery

  connection_dir_get_by_purpose_and_resource

  根据连接的属性从连接池中获取相应连接;

  connection_speaks_cells

  connection_is_listener

  connection_state_is_open

  connection_state_is_connecting

  判断函数,判断连接是否满足属性或具有一定状态;

  assert_connection_ok

  验证连接相关的变量均保持在正确范围内;

  connection_type_uses_bufferevent

  判断系统是否使用bufferevent,一般情况下为0;bufferevent作为子模块后期详细介绍;

4. 连接的代理

  connection_proxy_connect

  connection_read_proxy_handshake

  log_failed_proxy_connection

  get_proxy_addrport

  Proxy相关的功能,由于主流程中可以没有,暂时略去,作为后期描述的功能模块;

5. 连接的主要功能

  connection_connect

  为连接创建到远端目标的socket连接,是底层连接的最基本函数;

  retry_all_listeners

  为系统开启所有需要被监听的端口,创建监听连接;

  connection_handle_read

  connection_handle_write  <-  connection_flush

  为连接进行读写控制的函数,是读写回调函数的核心;

  alloc_http_authenticator ?

6. 连接的流量控制

  connection_bucket_init

  连接令牌桶进行初始化;

  connection_bucket_refill

  连接令牌桶进行令牌重填;

  connection_bucket_write_limit

  connection_bucket_read_limit

  输出连接当前可以使用的读写令牌数,即读写字节数;

  global_write_bucket_low

  判断系统当前是否处于写出缓冲区不足状态;

7. 连接的缓冲区控制

  connection_fetch_from_buf  ->  fetch_from_buf

  connection_fetch_from_buf_line  ->  fetch_from_buf_line

  connection_fetch_from_buf_http  ->  fetch_from_buf_http

  根据缓冲区内不同内容,进行不同方式的缓冲区读取;以上三个函数均调用Buffer.c文件中的缓冲区控制函数,所以只粗略介绍;

  connection_wants_to_flush

  connection_outbuf_too_full

  判断连接缓冲区是否有数据要写及是否要写数据过多;

  connection_write_to_buf  ->

  connection_write_to_buf_zlib  ->  _connection_write_to_buf_impl

  将需要输出的内容写入连接写缓冲区内,并要求连接开始写操作;

  connection_get_inbuf_len

  connection_get_outbuf_len

  获取连接读写缓冲区的内容长度;