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
获取连接读写缓冲区的内容长度;