通过上一节中我们对连接和链路的重新描述,我们可以继续进行源码的分析了。在本节中,我们会开始着重讲述链路的建立,以及链路所基于的OR连接的建立,同时还有部分Libevent调度的再度分析。大家会明白,进行到此处之时,我们已经开始接触Tor系统最底层,最深藏着的连接机制以及调度机制。这个部分,是整个系统的精髓。后期几乎所有的应用请求连接处理等,都是重复地使用该部分的代码。
1. 链路建立以及OR连接的开始,circuit_establish_circuit
我们在此处重新分析下链路建立的函数:
/** Build a new circuit for <b>purpose</b>. If <b>exit</b>
* is defined, then use that as your exit router, else choose a suitable
* exit node.
*
* Also launch a connection to the first OR in the chosen path, if
* it's not open already.
*/
origin_circuit_t *
circuit_establish_circuit(uint8_t purpose, extend_info_t *exit, int flags)
{
origin_circuit_t *circ;
int err_reason = 0;
circ = origin_circuit_init(purpose, flags); //链路初始化;
if (onion_pick_cpath_exit(circ, exit) < 0 || //选取链路出口结点;
onion_populate_cpath(circ) < 0) { //选取链路入口结点及中间结点;
......
}
if ((err_reason = circuit_handle_first_hop(circ)) < 0) { //开始向链路第一个结点发送建立OR连接的请求;(OR连接建立于TLS连接之上)
......
}
return circ;
}
像之前我们所描述的那样,函数内部主用做的工作包括三点:初始化链路结构体;选择链路结点;建立到链路中第一个结点的连接。此处需要说明的是,初始化链路结构体和选择链路结点的操作均是简单的。所以我们在接下来的分析中,不再详细追究这两个部分操作的具体细则,而是将我们的重心放在链路建立的实际操作部分。如果对选择结点部分有疑问,可以细细分析上述的两个结点选择函数,相信在其中可以找到结点选择策略和相关机制。但是&#