Tor 入口节点 Conflux 机制分析报告
1. 概述
Tor 的 Conflux 机制允许客户端在多个电路(circuits)之间分流流量,以提高抗审查性和网络性能。本报告分析入口节点在发送数据时,如何决定是否启用 Conflux 机制,以及在 Conflux 机制下,如何选择合适的电路进行数据传输。
2. 入口节点如何决定是否启用 Conflux 机制
在 Tor 入口节点发送数据时,会调用 circuit_establish_circuit_conflux
来建立 Conflux 电路,该函数的主要流程如下:
验证 Conflux 目的
1
tor_assert(purpose == CIRCUIT_PURPOSE_CONFLUX_UNLINKED);
入口节点仅在 CIRCUIT_PURPOSE_CONFLUX_UNLINKED 目的时才会使用 Conflux。
初始化电路
1
2
3circ = origin_circuit_init(purpose, flags);
TO_CIRCUIT(circ)->conflux_pending_nonce =
tor_memdup(conflux_nonce, DIGEST256_LEN);这里初始化了 Conflux 电路并存储了
conflux_nonce
。选择出口节点
1
2
3
4
5if (onion_pick_cpath_exit(circ, exit_ei, 0) < 0 ||
onion_populate_cpath(circ) < 0) {
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_NOPATH);
return NULL;
}若无法选择合适的出口节点,则直接关闭该电路。
建立连接
1
2
3
4if ((err_reason = circuit_handle_first_hop(circ)) < 0) {
circuit_mark_for_close(TO_CIRCUIT(circ), -err_reason);
return NULL;
}这里尝试连接到第一跳的 OR(Onion Router),如果失败则关闭电路。
3. 入口节点如何决定是否切换电路
当入口节点决定通过 Conflux 机制发送数据时,会调用 conflux_decide_circ_for_send
选择合适的电路。该函数的逻辑如下:
3.1 判断是否需要多路复用
1 | if (!conflux_should_multiplex(relay_command)) { |
如果当前的 relay_command
不支持多路复用,则直接使用原始电路。
3.2 选择下一个电路
1 | circuit_t *new_circ = conflux_decide_next_circ(cfx); |
调用 conflux_decide_next_circ
选择下一个电路。
3.3 处理非数据命令
1 | if (!new_circ && relay_command != RELAY_COMMAND_DATA) { |
如果当前无可用电路,但命令不是 RELAY_COMMAND_DATA
,则继续使用当前电路。
3.4 发送切换命令
1 | if (new_circ) { |
如果决定切换电路,则计算 relative_seq
并发送 SWITCH
命令。
4. 选择下一个电路的逻辑 (conflux_decide_next_circ
)
在 conflux_decide_circ_for_send
中调用 conflux_decide_next_circ
选择下一个电路,该函数的逻辑如下:
检查是否正在关闭
1
2
3if (cfx->in_full_teardown) {
return NULL;
}如果 Conflux 机制正在关闭,则不再选择新的电路。
初始化当前电路
1
2
3
4if (!cfx->curr_leg) {
if (!conflux_pick_first_leg(cfx))
return NULL;
}如果当前没有电路,则尝试选择第一个电路。
判断是否允许切换
1
2
3if (!conflux_can_switch(cfx)) {
return cfx->curr_leg->circ;
}如果不能切换,则返回当前电路。
根据不同策略选择电路
1
2
3
4
5
6
7
8
9
10switch (cfx->params.alg) {
case CONFLUX_ALG_MINRTT:
return (circuit_t*)conflux_decide_circ_minrtt(cfx);
case CONFLUX_ALG_LOWRTT:
return (circuit_t*)conflux_decide_circ_lowrtt(cfx);
case CONFLUX_ALG_CWNDRTT:
return (circuit_t*)conflux_decide_circ_cwndrtt(cfx);
default:
return NULL;
}其中:
CONFLUX_ALG_MINRTT
选择 RTT 最低的电路。CONFLUX_ALG_LOWRTT
选择高吞吐量但可能有乱序的电路。CONFLUX_ALG_CWNDRTT
选择考虑拥塞窗口的电路,以降低乱序问题。
5. 结论
Tor 入口节点在发送数据时,会根据目的和当前网络状况决定是否启用 Conflux 机制。如果 Conflux 机制被启用,则节点会基于 RTT、吞吐量或拥塞窗口选择最优的电路,并在合适的时机发送 SWITCH
命令以切换电路。通过这些策略,Tor 能够提高匿名性和数据传输效率。