TOR源码阅读(二)
今天阅读的内容是一段时间浏览后觉得有必要详细理解的部分,这里由于项目原因不进行具体的技术和语法等等分析,只做功能逻辑分析。
line 1008 in file main.c
run_connection_housekeeping(int i,time_t now) 函数,用于长期的单个连接上的持久性任务,被run_scheduled_ecents()每秒钟周期性调用。
我们来看它做了什么 获取第i个连接,获取当前配置选项结构体,判断当前时间是否超过连接生存周期,查看连接输出缓冲区是否已为空,若为空则进行标记,若连接标记为关闭,结束当前函数。
smartlist_get(connection_array, i);
or_options_t *options =
get_options();
NULL;
timestamp_lastwritten + options->
KeepalivePeriod;
outbuf && !
connection_get_outbuf_len(conn) &&
type == CONN_TYPE_OR)
timestamp_lastempty = now;
marked_for_close) {
。若连接类型为目录连接,连接活动超时(如果是服务器则为发送,如果为客户端则为接收),打印日志。判断连接目的是否为获取服务器的文件描述符,且读入缓冲已大于1024字节,若是则该连接已满,若不是,则标记连接为已关闭。若连接既非目录连接也非OR连接,则退出函数。
type == CONN_TYPE_DIR &&
DIR_CONN_IS_SERVER(conn) &&
timestamp_lastwritten
TestingDirConnectionMaxStall < now) ||
DIR_CONN_IS_SERVER(conn) &&
timestamp_lastread
TestingDirConnectionMaxStall < now))) {
“Expiring wedged directory conn (fd %d, purpose %d)”,
int)conn->
s, conn->
purpose);
purpose == DIR_PURPOSE_FETCH_SERVERDESC &&
1024) {
“Trying to extract information from wedged server desc “
TO_DIR_CONN(conn));
else {
connection_speaks_cells(conn))
连接为OR连接时,若通道上存在链路,则设置当前时间戳为有链路存在的最新时间。若通道上不适合产生新链路,且当前并无链路在其上,则标记之,且若连接状态为已连接,则放弃该连接。若连接并未打开,则连接正常关闭。若连接空闲,且无链路,输出缓冲区为空,则关闭之。若连接超时,也关闭之。若连接仍在生存期内但无数据待发送,则发送一个填充数据元保持链路可用。若均不是,即正常可用通道,则进行通道填充。
channel_is_bad_for_new_circs(
TLS_CHAN_TO_BASE(or_conn->
chan)) &&
int)conn->
s, conn->
address, conn->
port);
state == OR_CONN_STATE_CONNECTING)
TO_OR_CONN(conn),
TO_OR_CONN(conn),
1);
else
if (!
connection_state_is_open(conn)) {
“Expiring non-open OR connection to fd %d (%s:%d).”,
int)conn->
s,conn->
address, conn->
port);
TO_OR_CONN(conn),
0);
else
if (
we_are_hibernating() &&
connection_get_outbuf_len(conn)) {
“Expiring non-used OR connection to fd %d (%s:%d) “
int)conn->
s,conn->
address, conn->
port);
TO_OR_CONN(conn),
1);
else
if (!have_any_circuits &&
idle_timeout >=
timestamp_last_had_circuits) {
“Expiring non-used OR connection “U64_FORMAT
” to fd %d “
global_identifier),
int)conn->
s, conn->
address, conn->
port,
int)(now – chan->
timestamp_last_had_circuits),
idle_timeout,
is_canonical ?
“” :
“non”);
TO_OR_CONN(conn),
0);
else
if (
timestamp_lastempty + options->
KeepalivePeriod*
10 &&
timestamp_lastwritten + options->
KeepalivePeriod*
10) {
int)conn->
s, conn->
address, conn->
port,
int)
connection_get_outbuf_len(conn),
int)(now-conn->
timestamp_lastwritten));
TO_OR_CONN(conn),
0);
else
if (past_keepalive && !
connection_get_outbuf_len(conn)) {
“Sending keepalive to (%s:%d)”,
address, conn->
port);
0,
sizeof(
cell_t));
command = CELL_PADDING;
else {
开发者思维之缜密再一次使我惊叹,我们所关注的数据填充部分可以下移到channelpadding_decide_to_pad_channel(chan)上。因为我们可以探究若为可用OR连接时,他们会怎么进行通道的填充。