在上个小节中,已经基本分析了Tor系统的初始化过程。该过程中,最重要的部分,就是对默认配置文件、输入配置文件以及命令行参数进行综合整理,定出最后的配置方案。而后通过配置方案,启动系统的基础部分。这里值得说明的是,Tor系统的所有配置选项,均可以在Tor Manual中找到。并且,根据Tor系统配置成不同的身份,使用的配置选项也会有细微差别。默认的配置固化在代码内部,有兴趣的朋友可以就初始化部分往下深究。另外,笔者会将经自己简要翻译和分析过的Tor Manual在后续章节中给出。
1. 主命令的执行
在初始化过程中,系统将所有参数配置均最终写入到全局变量global_options之中。之后利用get_options()函数就可以随时获取系统配置和系统主命令。系统主命令在tor_main()函数中被使用,用于指示Tor程序启动的目的。
if (tor_init(argc, argv)<0)
return -1;
switch (get_options()->command) {
case CMD_RUN_TOR:
#ifdef NT_SERVICE
nt_service_set_state(SERVICE_RUNNING);
#endif
result = do_main_loop();
break;
case CMD_LIST_FINGERPRINT:
result = do_list_fingerprint();
break;
case CMD_HASH_PASSWORD:
do_hash_password();
result = 0;
break;
case CMD_VERIFY_CONFIG:
printf("Configuration was valid\n");
result = 0;
break;
case CMD_RUN_UNITTESTS: /* only set by test.c */
default:
log_warn(LD_BUG,"Illegal command number %d: internal error.",
get_options()->command);
result = -1;
}
这里我们只分析CMD_RUN_TOR命令下的系统主循环函数,也就是Tor系统的核心函数,不再继续讨论另外的主命令。
2. 主循环的初始化
主循环的初始化代码如下:
/* initialize dns resolve map, spawn workers if needed */
if (dns_init() < 0) {
if (get_options()->ServerDNSAllowBrokenConfig)
log_warn(LD_GENERAL, "Couldn't set up any working nameservers. "
"Network not up yet? Will try again soon.");
else {
log_err(LD_GENERAL,"Error initializing dns subsystem; exiting. To "
"retry instead, set the ServerDNSAllowBrokenResolvConf option.");
}
}
handle_signals(1);
/* load the private keys, if we're supposed to have them, and set up the
* TLS context. */
if (! client_identity_key_is_set()) {
if (init_keys() < 0) {
log_err(LD_BUG,"Error initializing keys; exiting");
return -1;
}
}
/* Set up the packed_cell_t memory pool. */
init_cell_pool();
/* Set up our buckets */
connection_bucket_init();
#ifndef USE_BUFFEREVENTS
stats_prev_global_read_bucket = global_read_bucket;
stats_prev_global_write_bucket = global_write_buc