📄 config.c
字号:
V(BWHistoryReadValues, CSV, ""),
V(BWHistoryWriteEnds, ISOTIME, NULL),
V(BWHistoryWriteInterval, UINT, "900"),
V(BWHistoryWriteValues, CSV, ""),
V(TorVersion, STRING, NULL),
V(LastRotatedOnionKey, ISOTIME, NULL),
V(LastWritten, ISOTIME, NULL),
{ NULL, CONFIG_TYPE_OBSOLETE, 0, NULL }
};
#undef VAR
#undef V
#undef OBSOLETE
/** Represents an English description of a configuration variable; used when
* generating configuration file comments. */
typedef struct config_var_description_t {
const char *name;
const char *description;
} config_var_description_t;
static config_var_description_t options_description[] = {
/* ==== general options */
{ "AvoidDiskWrites", "If non-zero, try to write to disk less frequently than"
" we would otherwise." },
{ "BandwidthRate", "A token bucket limits the average incoming bandwidth on "
"this node to the specified number of bytes per second." },
{ "BandwidthBurst", "Limit the maximum token buffer size (also known as "
"burst) to the given number of bytes." },
{ "ConnLimit", "Minimum number of simultaneous sockets we must have." },
{ "ConstrainedSockets", "Shrink tx and rx buffers for sockets to avoid "
"system limits on vservers and related environments. See man page for "
"more information regarding this option." },
{ "ConstrainedSockSize", "Limit socket buffers to this size when "
"ConstrainedSockets is enabled." },
/* ControlListenAddress */
{ "ControlPort", "If set, Tor will accept connections from the same machine "
"(localhost only) on this port, and allow those connections to control "
"the Tor process using the Tor Control Protocol (described in"
"control-spec.txt).", },
{ "CookieAuthentication", "If this option is set to 1, don't allow any "
"connections to the control port except when the connecting process "
"can read a file that Tor creates in its data directory." },
{ "DataDirectory", "Store working data, state, keys, and caches here." },
{ "DirServer", "Tor only trusts directories signed with one of these "
"servers' keys. Used to override the standard list of directory "
"authorities." },
/* { "FastFirstHopPK", "" }, */
/* FetchServerDescriptors, FetchHidServDescriptors,
* FetchUselessDescriptors */
{ "Group", "On startup, setgid to this group." },
{ "HardwareAccel", "If set, Tor tries to use hardware crypto accelerators "
"when it can." },
/* HashedControlPassword */
{ "HTTPProxy", "Force Tor to make all HTTP directory requests through this "
"host:port (or host:80 if port is not set)." },
{ "HTTPProxyAuthenticator", "A username:password pair to be used with "
"HTTPProxy." },
{ "HTTPSProxy", "Force Tor to make all TLS (SSL) connectinos through this "
"host:port (or host:80 if port is not set)." },
{ "HTTPSProxyAuthenticator", "A username:password pair to be used with "
"HTTPSProxy." },
{ "KeepalivePeriod", "Send a padding cell every N seconds to keep firewalls "
"from closing our connections while Tor is not in use." },
{ "Log", "Where to send logging messages. Format is "
"minSeverity[-maxSeverity] (stderr|stdout|syslog|file FILENAME)." },
{ "OutboundBindAddress", "Make all outbound connections originate from the "
"provided IP address (only useful for multiple network interfaces)." },
{ "PIDFile", "On startup, write our PID to this file. On clean shutdown, "
"remove the file." },
{ "PreferTunneledDirConns", "If non-zero, avoid directory servers that "
"don't support tunneled connections." },
/* PreferTunneledDirConns */
/* ProtocolWarnings */
/* RephistTrackTime */
{ "RunAsDaemon", "If set, Tor forks and daemonizes to the background when "
"started. Unix only." },
{ "SafeLogging", "If set to 0, Tor logs potentially sensitive strings "
"rather than replacing them with the string [scrubbed]." },
{ "TunnelDirConns", "If non-zero, when a directory server we contact "
"supports it, we will build a one-hop circuit and make an encrypted "
"connection via its ORPort." },
{ "User", "On startup, setuid to this user" },
/* ==== client options */
{ "AllowInvalidNodes", "Where on our circuits should Tor allow servers "
"that the directory authorities haven't called \"valid\"?" },
{ "AllowNonRFC953Hostnames", "If set to 1, we don't automatically reject "
"hostnames for having invalid characters." },
/* CircuitBuildTimeout, CircuitIdleTimeout */
{ "ClientOnly", "If set to 1, Tor will under no circumstances run as a "
"server, even if ORPort is enabled." },
{ "EntryNodes", "A list of preferred entry nodes to use for the first hop "
"in circuits, when possible." },
/* { "EnforceDistinctSubnets" , "" }, */
{ "ExitNodes", "A list of preferred nodes to use for the last hop in "
"circuits, when possible." },
{ "ExcludeNodes", "A list of nodes never to use when building a circuit." },
{ "FascistFirewall", "If set, Tor will only create outgoing connections to "
"servers running on the ports listed in FirewallPorts." },
{ "FirewallPorts", "A list of ports that we can connect to. Only used "
"when FascistFirewall is set." },
{ "LongLivedPorts", "A list of ports for services that tend to require "
"high-uptime connections." },
{ "MapAddress", "Force Tor to treat all requests for one address as if "
"they were for another." },
{ "NewCircuitPeriod", "Force Tor to consider whether to build a new circuit "
"every NUM seconds." },
{ "MaxCircuitDirtiness", "Do not attach new streams to a circuit that has "
"been used more than this many seconds ago." },
/* NatdPort, NatdListenAddress */
{ "NodeFamily", "A list of servers that constitute a 'family' and should "
"never be used in the same circuit." },
{ "NumEntryGuards", "How many entry guards should we keep at a time?" },
/* PathlenCoinWeight */
{ "ReachableAddresses", "Addresses we can connect to, as IP/bits:port-port. "
"By default, we assume all addresses are reachable." },
/* reachablediraddresses, reachableoraddresses. */
{ "RendNodes", "A list of preferred nodes to use for a rendezvous point, "
"when possible." },
{ "RendExcludenodes", "A list of nodes never to use as rendezvous points." },
/* SafeSOCKS */
{ "SOCKSPort", "The port where we listen for SOCKS connections from "
"applications." },
{ "SOCKSListenAddress", "Bind to this address to listen to connections from "
"SOCKS-speaking applications." },
{ "SOCKSPolicy", "Set an entry policy to limit which addresses can connect "
"to the SOCKSPort." },
/* SocksTimeout */
{ "StrictExitNodes", "If set, Tor will fail to operate when none of the "
"configured ExitNodes can be used." },
{ "StrictEntryNodes", "If set, Tor will fail to operate when none of the "
"configured EntryNodes can be used." },
/* TestSocks */
{ "TrackHostsExit", "Hosts and domains which should, if possible, be "
"accessed from the same exit node each time we connect to them." },
{ "TrackHostsExitExpire", "Time after which we forget which exit we were "
"using to connect to hosts in TrackHostsExit." },
/* "TransPort", "TransListenAddress */
{ "UseEntryGuards", "Set to 0 if we want to pick from the whole set of "
"servers for the first position in each circuit, rather than picking a "
"set of 'Guards' to prevent profiling attacks." },
/* === server options */
{ "Address", "The advertised (external) address we should use." },
/* Accounting* options. */
/* AssumeReachable */
{ "ContactInfo", "Administrative contact information to advertise for this "
"server." },
{ "ExitPolicy", "Address/port ranges for which to accept or reject outgoing "
"connections on behalf of Tor users." },
/* { "ExitPolicyRejectPrivate, "" }, */
{ "MaxAdvertisedBandwidth", "If set, we will not advertise more than this "
"amount of bandwidth for our bandwidth rate, regardless of how much "
"bandwidth we actually detect." },
{ "MaxOnionsPending", "Reject new attempts to extend circuits when we "
"already have this many pending." },
{ "MyFamily", "Declare a list of other servers as belonging to the same "
"family as this one, so that clients will not use two from the same "
"family in the same circuit." },
{ "Nickname", "Set the server nickname." },
{ "NoPublish", "{DEPRECATED}" },
{ "NumCPUs", "How many processes to use at once for public-key crypto." },
{ "ORPort", "Advertise this port to listen for connections from Tor clients "
"and servers." },
{ "ORListenAddress", "Bind to this address to listen for connections from "
"clients and servers, instead of the default 0.0.0.0:ORPort." },
{ "PublishServerDescriptor", "Set to 0 to keep the server from "
"uploading info to the directory authorities." },
/*{ "RedirectExit", "When an outgoing connection tries to connect to a "
*"given address, redirect it to another address instead." },
*/
/* ServerDNS: DetectHijacking, ResolvConfFile, SearchDomains */
{ "ShutdownWaitLength", "Wait this long for clients to finish when "
"shutting down because of a SIGINT." },
/* { "TestVia", } */
/* === directory cache options */
{ "DirPort", "Serve directory information from this port, and act as a "
"directory cache." },
{ "DirListenAddress", "Bind to this address to listen for connections from "
"clients and servers, instead of the default 0.0.0.0:DirPort." },
{ "DirPolicy", "Set a policy to limit who can connect to the directory "
"port" },
/* Authority options: AuthDirBadExit, AuthDirInvalid, AuthDirReject,
* AuthDirRejectUnlisted, AuthDirListBadExits, AuthoritativeDirectory,
* DirAllowPrivateAddresses, HSAuthoritativeDir,
* NamingAuthoritativeDirectory, RecommendedVersions,
* RecommendedClientVersions, RecommendedServerVersions, RendPostPeriod,
* RunTesting, V1AuthoritativeDirectory, VersioningAuthoritativeDirectory, */
/* Hidden service options: HiddenService: dir,excludenodes, nodes,
* options, port. PublishHidServDescriptor */
/* Nonpersistent options: __LeaveStreamsUnattached, __AllDirActionsPrivate */
{ NULL, NULL },
};
static config_var_description_t state_description[] = {
{ "AccountingBytesReadInInterval",
"How many bytes have we read in this accounting period?" },
{ "AccountingBytesWrittenInInterval",
"How many bytes have we written in this accounting period?" },
{ "AccountingExpectedUsage",
"How many bytes did we expect to use per minute? (0 for no estimate.)" },
{ "AccountingIntervalStart", "When did this accounting period begin?" },
{ "AccountingSecondsActive", "How long have we been awake in this period?" },
{ "BWHistoryReadEnds", "When does the last-recorded read-interval end?" },
{ "BWHistoryReadInterval", "How long is each read-interval (in seconds)?" },
{ "BWHistoryReadValues", "Number of bytes read in each interval." },
{ "BWHistoryWriteEnds", "When does the last-recorded write-interval end?" },
{ "BWHistoryWriteInterval", "How long is each write-interval (in seconds)?"},
{ "BWHistoryWriteValues", "Number of bytes written in each interval." },
{ "EntryGuard", "One of the nodes we have chosen as a fixed entry" },
{ "EntryGuardDownSince",
"The last entry guard has been unreachable since this time." },
{ "EntryGuardUnlistedSince",
"The last entry guard has been unusable since this time." },
{ "LastRotatedOnionKey",
"The last time at which we changed the medium-term private key used for "
"building circuits." },
{ "LastWritten", "When was this state file last regenerated?" },
{ "TorVersion", "Which version of Tor generated this state file?" },
{ NULL, NULL },
};
/** Type of a callback to validate whether a given configuration is
* well-formed and consistent. See options_trial_assign() for documentation
* of arguments. */
typedef int (*validate_fn_t)(void*,void*,int,char**);
/** Information on the keys, value types, key-to-struct-member mappings,
* variable descriptions, validation functions, and abbreviations for a
* configuration or storage format. */
typedef struct {
size_t size; /**< Size of the struct that everything gets parsed into. */
uint32_t magic; /**< Required 'magic value' to make sure we have a struct
* of the right type. */
off_t magic_offset; /**< Offset of the magic value within the struct. */
config_abbrev_t *abbrevs; /**< List of abbreviations that we expand when
* parsing this format. */
config_var_t *vars; /**< List of variables we recognize, their default
* values, and where we stick them in the structure. */
validate_fn_t validate_fn; /**< Function to validate config. */
/** Documentation for configuration variables. */
config_var_description_t *descriptions;
/** If present, extra is a LINELIST variable for unrecognized
* lines. Otherwise, unrecognized lines are an error. */
config_var_t *extra;
} config_format_t;
/** Macro: assert that <b>cfg</b> has the right magic field for format
* <b>fmt</b>. */
#define CHECK(fmt, cfg) STMT_BEGIN \
tor_assert(fmt && cfg); \
tor_assert((fmt)->magic == \
*(uint32_t*)STRUCT_VAR_P(cfg,fmt->magic_offset)); \
STMT_END
static void config_line_append(config_line_t **lst,
const char *key, const char *val);
static void option_clear(config_format_t *fmt, or_options_t *options,
config_var_t *var);
static void option_reset(config_format_t *fmt, or_options_t *options,
config_var_t *var, int use_defaults);
static void config_free(config_format_t *fmt, void *options);
static int config_lines_eq(config_line_t *a, config_line_t *b);
static int option_is_same(config_format_t *fmt,
or_options_t *o1, or_options_t *o2,
const char *name);
static or_options_t *options_dup(config_format_t *fmt, or_options_t *old);
static int options_validate(or_options_t *old_options, or_options_t *options,
int from_setconf, char **msg);
static int options_act_reversible(or_options_t *old_options, char **msg);
static int options_act(or_options_t *old_options);
static int options_transition_allowed(or_options_t *old, or_options_t *new,
char **msg);
static int options_transition_affects_workers(or_options_t *old_options,
or_options_t *new_options);
static int options_transition_affects_descriptor(or_options_t *old_options,
or_options_t *new_options);
static int check_nickname_list(const char *lst, const char *name, char **msg);
static void config_register_addressmaps(or_options_t *options);
static int parse_bridge_line(const char *line, int validate_only);
static int parse_dir_server_line(const char *line,
authority_type_t required_type,
int validate_only);
static int parse_redirect_line(smartlist_t *result,
config_line_t *line, char **msg);
static int validate_data_directory(or_options_t *options);
static int write_configuration_file(const char *fname, or_options_t *options);
static config_line_t *get_assigned_option(config_format_t *fmt,
or_options_t *options, const char *key,
int escape_val);
static void config_init(config_format_t *fmt, void *options);
static int or_state_validate(or_state_t *old_options, or_state_t *options,
int from_setconf, char **msg);
static int or_state_load(void);
static int options_init_logs(or_options_t *options, int validate_only);
static uint64_t config_parse_memunit(const char *s, int *ok);
static int config_parse_interval(const char *s, int *ok);
static void print_svn_version(void);
static void init_libevent(void);
static int opt_streq(const char *s1, const char *s2);
/** Versions of libevent. */
typedef enum {
/* Note: we compare these, so it's important that "old" precede everything,
* and that "other" come last. */
LE_OLD=0, LE_10C, LE_10D, LE_10E, LE_11, LE_11A, LE_11B, LE_12, LE_12A,
LE_13, LE_13A, LE_13B, LE_13C, LE_13D,
LE_OTHER
} le_version_t;
static le_version_t decode_libevent_version(void);
#if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
static void check_libevent_version(const char *m, int server);
#endif
/** Magic value for or_options_t. */
#define OR_OPTIONS_MAGIC 9090909
/** Configuration format for or_options_t. */
static config_format_t options_format = {
sizeof(or_options_t),
OR_OPTIONS_MAGIC,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -