📄 config.c
字号:
STRUCT_OFFSET(or_options_t, _magic),
_option_abbrevs,
_option_vars,
(validate_fn_t)options_validate,
options_description,
NULL
};
/** Magic value for or_state_t. */
#define OR_STATE_MAGIC 0x57A73f57
/** "Extra" variable in the state that receives lines we can't parse. This
* lets us preserve options from versions of Tor newer than us. */
static config_var_t state_extra_var = {
"__extra", CONFIG_TYPE_LINELIST, STRUCT_OFFSET(or_state_t, ExtraLines), NULL
};
/** Configuration format for or_state_t. */
static config_format_t state_format = {
sizeof(or_state_t),
OR_STATE_MAGIC,
STRUCT_OFFSET(or_state_t, _magic),
_state_abbrevs,
_state_vars,
(validate_fn_t)or_state_validate,
state_description,
&state_extra_var,
};
/*
* Functions to read and write the global options pointer.
*/
/** Command-line and config-file options. */
static or_options_t *global_options = NULL;
/** Name of most recently read torrc file. */
static char *torrc_fname = NULL;
/** Persistent serialized state. */
static or_state_t *global_state = NULL;
/** Configuration Options set by command line. */
static config_line_t *global_cmdline_options = NULL;
/** Allocate an empty configuration object of a given format type. */
static void *
config_alloc(config_format_t *fmt)
{
void *opts = tor_malloc_zero(fmt->size);
*(uint32_t*)STRUCT_VAR_P(opts, fmt->magic_offset) = fmt->magic;
CHECK(fmt, opts);
return opts;
}
/** Return the currently configured options. */
or_options_t *
get_options(void)
{
tor_assert(global_options);
return global_options;
}
/** Change the current global options to contain <b>new_val</b> instead of
* their current value; take action based on the new value; free the old value
* as necessary. Returns 0 on success, -1 on failure.
*/
int
set_options(or_options_t *new_val, char **msg)
{
or_options_t *old_options = global_options;
global_options = new_val;
/* Note that we pass the *old* options below, for comparison. It
* pulls the new options directly out of global_options. */
if (options_act_reversible(old_options, msg)<0) {
tor_assert(*msg);
global_options = old_options;
return -1;
}
if (options_act(old_options) < 0) { /* acting on the options failed. die. */
log_err(LD_BUG,
"Acting on config options left us in a broken state. Dying.");
exit(1);
}
if (old_options)
config_free(&options_format, old_options);
return 0;
}
extern const char tor_svn_revision[]; /* from tor_main.c */
static char *_version = NULL;
/** Return the current Tor version, possibly */
const char *
get_version(void)
{
if (_version == NULL) {
if (strlen(tor_svn_revision)) {
size_t len = strlen(VERSION)+strlen(tor_svn_revision)+8;
_version = tor_malloc(len);
tor_snprintf(_version, len, "%s (r%s)", VERSION, tor_svn_revision);
} else {
_version = tor_strdup(VERSION);
}
}
return _version;
}
/** Release all memory and resources held by global configuration structures.
*/
void
config_free_all(void)
{
if (global_options) {
config_free(&options_format, global_options);
global_options = NULL;
}
if (global_state) {
config_free(&state_format, global_state);
global_state = NULL;
}
if (global_cmdline_options) {
config_free_lines(global_cmdline_options);
global_cmdline_options = NULL;
}
tor_free(torrc_fname);
tor_free(_version);
}
/** If options->SafeLogging is on, return a not very useful string,
* else return address.
*/
const char *
safe_str(const char *address)
{
tor_assert(address);
if (get_options()->SafeLogging)
return "[scrubbed]";
else
return address;
}
/** Equivalent to escaped(safe_str(address)). See reentrancy note on
* escaped(): don't use this outside the main thread, or twice in the same
* log statement. */
const char *
escaped_safe_str(const char *address)
{
if (get_options()->SafeLogging)
return "[scrubbed]";
else
return escaped(address);
}
/** Add the default directory authorities directly into the trusted dir list,
* but only add them insofar as they share bits with <b>type</b>. */
static void
add_default_trusted_dir_authorities(authority_type_t type)
{
int i;
const char *dirservers[] = {
"moria1 v1 orport=9001 v3ident=5420FD8EA46BD4290F1D07A1883C9D85ECC486C4 "
"128.31.0.34:9031 FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441",
"moria2 v1 orport=9002 128.31.0.34:9032 "
"719B E45D E224 B607 C537 07D0 E214 3E2D 423E 74CF",
"tor26 v1 orport=443 v3ident=A9AC67E64B200BBF2FA26DF194AC0469E2A948C6 "
"86.59.21.38:80 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D",
"lefkada orport=443 "
"140.247.60.64:80 38D4 F5FC F7B1 0232 28B8 95EA 56ED E7D5 CCDC AF32",
"dizum orport=443 v3ident=E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58 "
"194.109.206.212:80 7EA6 EAD6 FD83 083C 538F 4403 8BBF A077 587D D755",
"Tonga orport=443 bridge no-v2 82.94.251.206:80 "
"4A0C CD2D DC79 9508 3D73 F5D6 6710 0C8A 5831 F16D",
"ides orport=9090 no-v2 v3ident=27B6B5996C426270A5C95488AA5BCEB6BCC86956 "
"216.224.124.114:9030 F397 038A DC51 3361 35E7 B80B D99C A384 4360 292B",
"gabelmoo orport=443 no-v2 "
"v3ident=EAA879B5C75032E462CB018630D2D0DF46EBA606 "
"88.198.7.215:80 6833 3D07 61BC F397 A587 A0C0 B963 E4A9 E99E C4D3",
"dannenberg orport=443 no-v2 "
"v3ident=585769C78764D58426B8B52B6651A5A71137189A "
"213.73.91.31:80 7BE6 83E6 5D48 1413 21C5 ED92 F075 C553 64AC 7123",
NULL
};
for (i=0; dirservers[i]; i++) {
if (parse_dir_server_line(dirservers[i], type, 0)<0) {
log_err(LD_BUG, "Couldn't parse internal dirserver line %s",
dirservers[i]);
}
}
}
/** Look at all the config options for using alternate directory
* authorities, and make sure none of them are broken. Also, warn the
* user if we changed any dangerous ones.
*/
static int
validate_dir_authorities(or_options_t *options, or_options_t *old_options)
{
config_line_t *cl;
if (options->DirServers &&
(options->AlternateDirAuthority || options->AlternateBridgeAuthority ||
options->AlternateHSAuthority)) {
log_warn(LD_CONFIG,
"You cannot set both DirServers and Alternate*Authority.");
return -1;
}
/* do we want to complain to the user about being partitionable? */
if ((options->DirServers &&
(!old_options ||
!config_lines_eq(options->DirServers, old_options->DirServers))) ||
(options->AlternateDirAuthority &&
(!old_options ||
!config_lines_eq(options->AlternateDirAuthority,
old_options->AlternateDirAuthority)))) {
log_warn(LD_CONFIG,
"You have used DirServer or AlternateDirAuthority to "
"specify alternate directory authorities in "
"your configuration. This is potentially dangerous: it can "
"make you look different from all other Tor users, and hurt "
"your anonymity. Even if you've specified the same "
"authorities as Tor uses by default, the defaults could "
"change in the future. Be sure you know what you're doing.");
}
/* Now go through the four ways you can configure an alternate
* set of directory authorities, and make sure none are broken. */
for (cl = options->DirServers; cl; cl = cl->next)
if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
return -1;
for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
return -1;
for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
return -1;
for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
if (parse_dir_server_line(cl->value, NO_AUTHORITY, 1)<0)
return -1;
return 0;
}
/** Look at all the config options and assign new dir authorities
* as appropriate.
*/
static int
consider_adding_dir_authorities(or_options_t *options,
or_options_t *old_options)
{
config_line_t *cl;
int need_to_update =
!smartlist_len(router_get_trusted_dir_servers()) || !old_options ||
!config_lines_eq(options->DirServers, old_options->DirServers) ||
!config_lines_eq(options->AlternateBridgeAuthority,
old_options->AlternateBridgeAuthority) ||
!config_lines_eq(options->AlternateDirAuthority,
old_options->AlternateDirAuthority) ||
!config_lines_eq(options->AlternateHSAuthority,
old_options->AlternateHSAuthority);
if (!need_to_update)
return 0; /* all done */
/* Start from a clean slate. */
clear_trusted_dir_servers();
if (!options->DirServers) {
/* then we may want some of the defaults */
authority_type_t type = NO_AUTHORITY;
if (!options->AlternateBridgeAuthority)
type |= BRIDGE_AUTHORITY;
if (!options->AlternateDirAuthority)
type |= V1_AUTHORITY | V2_AUTHORITY | V3_AUTHORITY;
if (!options->AlternateHSAuthority)
type |= HIDSERV_AUTHORITY;
add_default_trusted_dir_authorities(type);
}
for (cl = options->DirServers; cl; cl = cl->next)
if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
return -1;
for (cl = options->AlternateBridgeAuthority; cl; cl = cl->next)
if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
return -1;
for (cl = options->AlternateDirAuthority; cl; cl = cl->next)
if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
return -1;
for (cl = options->AlternateHSAuthority; cl; cl = cl->next)
if (parse_dir_server_line(cl->value, NO_AUTHORITY, 0)<0)
return -1;
return 0;
}
/** Fetch the active option list, and take actions based on it. All of the
* things we do should survive being done repeatedly. If present,
* <b>old_options</b> contains the previous value of the options.
*
* Return 0 if all goes well, return -1 if things went badly.
*/
static int
options_act_reversible(or_options_t *old_options, char **msg)
{
smartlist_t *new_listeners = smartlist_create();
smartlist_t *replaced_listeners = smartlist_create();
static int libevent_initialized = 0;
or_options_t *options = get_options();
int running_tor = options->command == CMD_RUN_TOR;
int set_conn_limit = 0;
int r = -1;
int logs_marked = 0;
/* Daemonize _first_, since we only want to open most of this stuff in
* the subprocess. Libevent bases can't be reliably inherited across
* processes. */
if (running_tor && options->RunAsDaemon) {
/* No need to roll back, since you can't change the value. */
start_daemon();
}
#ifndef HAVE_SYS_UN_H
if (options->ControlSocket) {
*msg = tor_strdup("Unix domain sockets (ControlSocket) not supported"
" on this OS/with this build.");
goto rollback;
}
#endif
if (running_tor) {
/* We need to set the connection limit before we can open the listeners. */
if (set_max_file_descriptors((unsigned)options->ConnLimit,
&options->_ConnLimit) < 0) {
*msg = tor_strdup("Problem with ConnLimit value. See logs for details.");
goto rollback;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -