1 /* Copyright (c) 2001 Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. */
4 /* See LICENSE for licensing information */
6 const char config_c_id
[] = \
11 * \brief Code to parse and interpret configuration files.
18 #include "../common/aes.h"
20 /** Enumeration of types which option values can take */
21 typedef enum config_type_t
{
22 CONFIG_TYPE_STRING
= 0, /**< An arbitrary string. */
23 CONFIG_TYPE_UINT
, /**< A non-negative integer less than MAX_INT */
24 CONFIG_TYPE_INTERVAL
, /**< A number of seconds, with optional units*/
25 CONFIG_TYPE_MEMUNIT
, /**< A number of bytes, with optional units*/
26 CONFIG_TYPE_DOUBLE
, /**< A floating-point value */
27 CONFIG_TYPE_BOOL
, /**< A boolean value, expressed as 0 or 1. */
28 CONFIG_TYPE_ISOTIME
, /**< An ISO-formated time relative to GMT. */
29 CONFIG_TYPE_CSV
, /**< A list of strings, separated by commas and
30 * optional whitespace. */
31 CONFIG_TYPE_LINELIST
, /**< Uninterpreted config lines */
32 CONFIG_TYPE_LINELIST_S
, /**< Uninterpreted, context-sensitive config lines,
33 * mixed with other keywords. */
34 CONFIG_TYPE_LINELIST_V
, /**< Catch-all "virtual" option to summarize
35 * context-sensitive config lines when fetching.
37 CONFIG_TYPE_OBSOLETE
, /**< Obsolete (ignored) option. */
40 /** An abbreviation for a configuration option allowed on the command line. */
41 typedef struct config_abbrev_t
{
42 const char *abbreviated
;
48 /* Handy macro for declaring "In the config file or on the command line,
49 * you can abbreviate <b>tok</b>s as <b>tok</b>". */
50 #define PLURAL(tok) { #tok, #tok "s", 0, 0 }
52 /* A list of command-line abbreviations. */
53 static config_abbrev_t _option_abbrevs
[] = {
58 PLURAL(LongLivedPort
),
59 PLURAL(HiddenServiceNode
),
60 PLURAL(HiddenServiceExcludeNode
),
63 PLURAL(RendExcludeNode
),
64 PLURAL(StrictEntryNode
),
65 PLURAL(StrictExitNode
),
67 { "AllowUnverifiedNodes", "AllowInvalidNodes", 0, 0},
68 { "BandwidthRateBytes", "BandwidthRate", 0, 0},
69 { "BandwidthBurstBytes", "BandwidthBurst", 0, 0},
70 { "DirFetchPostPeriod", "StatusFetchPeriod", 0, 0},
71 { "MaxConn", "ConnLimit", 0, 1},
72 { "ORBindAddress", "ORListenAddress", 0, 0},
73 { "DirBindAddress", "DirListenAddress", 0, 0},
74 { "SocksBindAddress", "SocksListenAddress", 0, 0},
75 { "UseHelperNodes", "UseEntryGuards", 0, 0},
76 { "NumHelperNodes", "NumEntryGuards", 0, 0},
77 { "UseEntryNodes", "UseEntryGuards", 0, 0},
78 { "NumEntryNodes", "NumEntryGuards", 0, 0},
81 /* A list of state-file abbreviations, for compatibility. */
82 static config_abbrev_t _state_abbrevs
[] = {
83 { "AccountingBytesReadInterval", "AccountingBytesReadInInterval", 0, 0 },
84 { "HelperNode", "EntryGuard", 0, 0 },
85 { "HelperNodeDownSince", "EntryGuardDownSince", 0, 0 },
86 { "HelperNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
87 { "EntryNode", "EntryGuard", 0, 0 },
88 { "EntryNodeDownSince", "EntryGuardDownSince", 0, 0 },
89 { "EntryNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
94 /** A variable allowed in the configuration file or on the command line. */
95 typedef struct config_var_t
{
96 const char *name
; /**< The full keyword (case insensitive). */
97 config_type_t type
; /**< How to interpret the type and turn it into a
99 off_t var_offset
; /**< Offset of the corresponding member of or_options_t. */
100 const char *initvalue
; /**< String (or null) describing initial value. */
103 /** Return the offset of <b>member</b> within the type <b>tp</b>, in bytes */
104 #define STRUCT_OFFSET(tp, member) \
105 ((off_t) (((char*)&((tp*)0)->member)-(char*)0))
107 #define STRUCT_VAR_P(st, off) \
108 ((void*) ( ((char*)st) + off ) )
110 /** An entry for config_vars: "The option <b>name</b> has type
111 * CONFIG_TYPE_<b>conftype</b>, and corresponds to
112 * or_options_t.<b>member</b>"
114 #define VAR(name,conftype,member,initvalue) \
115 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_options_t, member), \
117 /** An entry for config_vars: "The option <b>name</b> is obsolete." */
118 #define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL }
120 /** Array of configuration options. Until we disallow nonstandard
121 * abbreviations, order is significant, since the first matching option will
124 static config_var_t _option_vars
[] = {
125 VAR("AccountingMax", MEMUNIT
, AccountingMax
, "0 bytes"),
126 VAR("AccountingMaxKB", UINT
, _AccountingMaxKB
, "0"),
127 VAR("AccountingStart", STRING
, AccountingStart
, NULL
),
128 VAR("Address", STRING
, Address
, NULL
),
129 VAR("__AllDirActionsPrivate",BOOL
, AllDirActionsPrivate
, "0"),
130 VAR("AllowInvalidNodes", CSV
, AllowInvalidNodes
,
131 "middle,rendezvous"),
132 VAR("AssumeReachable", BOOL
, AssumeReachable
, "0"),
133 VAR("AuthDirInvalid", LINELIST
, AuthDirInvalid
, NULL
),
134 VAR("AuthDirReject", LINELIST
, AuthDirReject
, NULL
),
135 VAR("AuthDirRejectUnlisted",BOOL
, AuthDirRejectUnlisted
,"0"),
136 VAR("AuthoritativeDirectory",BOOL
, AuthoritativeDir
, "0"),
137 VAR("BandwidthBurst", MEMUNIT
, BandwidthBurst
, "6 MB"),
138 VAR("BandwidthRate", MEMUNIT
, BandwidthRate
, "3 MB"),
139 VAR("CircuitBuildTimeout", INTERVAL
, CircuitBuildTimeout
, "1 minute"),
140 VAR("CircuitIdleTimeout", INTERVAL
, CircuitIdleTimeout
, "1 hour"),
141 VAR("ClientOnly", BOOL
, ClientOnly
, "0"),
142 VAR("ConnLimit", UINT
, ConnLimit
, "1000"),
143 VAR("ContactInfo", STRING
, ContactInfo
, NULL
),
144 VAR("ControlListenAddress",LINELIST
, ControlListenAddress
, NULL
),
145 VAR("ControlPort", UINT
, ControlPort
, "0"),
146 VAR("CookieAuthentication",BOOL
, CookieAuthentication
, "0"),
147 VAR("DataDirectory", STRING
, DataDirectory
, NULL
),
148 VAR("DebugLogFile", STRING
, DebugLogFile
, NULL
),
149 VAR("DirAllowPrivateAddresses",BOOL
, DirAllowPrivateAddresses
, NULL
),
150 VAR("DirListenAddress", LINELIST
, DirListenAddress
, NULL
),
151 /* if DirFetchPeriod is 0, see get_dir_fetch_period() in main.c */
152 VAR("DirFetchPeriod", INTERVAL
, DirFetchPeriod
, "0 seconds"),
153 VAR("DirPolicy", LINELIST
, DirPolicy
, NULL
),
154 VAR("DirPort", UINT
, DirPort
, "0"),
155 OBSOLETE("DirPostPeriod"),
156 VAR("DirServer", LINELIST
, DirServers
, NULL
),
157 VAR("EntryNodes", STRING
, EntryNodes
, NULL
),
158 VAR("ExcludeNodes", STRING
, ExcludeNodes
, NULL
),
159 VAR("ExitNodes", STRING
, ExitNodes
, NULL
),
160 VAR("ExitPolicy", LINELIST
, ExitPolicy
, NULL
),
161 VAR("ExitPolicyRejectPrivate", BOOL
, ExitPolicyRejectPrivate
, "1"),
162 VAR("FascistFirewall", BOOL
, FascistFirewall
, "0"),
163 VAR("FirewallPorts", CSV
, FirewallPorts
, ""),
164 VAR("FastFirstHopPK", BOOL
, FastFirstHopPK
, "1"),
165 VAR("FetchServerDescriptors",BOOL
, FetchServerDescriptors
,"1"),
166 VAR("FetchHidServDescriptors",BOOL
, FetchHidServDescriptors
, "1"),
167 VAR("FetchUselessDescriptors",BOOL
, FetchUselessDescriptors
, "0"),
168 VAR("Group", STRING
, Group
, NULL
),
169 VAR("HardwareAccel", BOOL
, HardwareAccel
, "0"),
170 VAR("HashedControlPassword",STRING
, HashedControlPassword
, NULL
),
171 VAR("HiddenServiceDir", LINELIST_S
, RendConfigLines
, NULL
),
172 VAR("HiddenServiceExcludeNodes", LINELIST_S
, RendConfigLines
, NULL
),
173 VAR("HiddenServiceNodes", LINELIST_S
, RendConfigLines
, NULL
),
174 VAR("HiddenServiceOptions",LINELIST_V
, RendConfigLines
, NULL
),
175 VAR("HiddenServicePort", LINELIST_S
, RendConfigLines
, NULL
),
176 VAR("HttpProxy", STRING
, HttpProxy
, NULL
),
177 VAR("HttpProxyAuthenticator",STRING
, HttpProxyAuthenticator
,NULL
),
178 VAR("HttpsProxy", STRING
, HttpsProxy
, NULL
),
179 VAR("HttpsProxyAuthenticator",STRING
,HttpsProxyAuthenticator
,NULL
),
180 OBSOLETE("IgnoreVersion"),
181 VAR("KeepalivePeriod", INTERVAL
, KeepalivePeriod
, "5 minutes"),
182 VAR("Log", LINELIST
, Logs
, NULL
),
183 OBSOLETE("LinkPadding"),
184 VAR("LogFile", LINELIST_S
, OldLogOptions
, NULL
),
185 VAR("LogLevel", LINELIST_S
, OldLogOptions
, NULL
),
186 VAR("LongLivedPorts", CSV
, LongLivedPorts
,
187 "21,22,706,1863,5050,5190,5222,5223,6667,8300,8888"),
188 VAR("MapAddress", LINELIST
, AddressMap
, NULL
),
189 VAR("MaxAdvertisedBandwidth",MEMUNIT
,MaxAdvertisedBandwidth
,"128 TB"),
190 VAR("MaxCircuitDirtiness", INTERVAL
, MaxCircuitDirtiness
, "10 minutes"),
191 VAR("MaxOnionsPending", UINT
, MaxOnionsPending
, "100"),
192 OBSOLETE("MonthlyAccountingStart"),
193 VAR("MyFamily", STRING
, MyFamily
, NULL
),
194 VAR("NewCircuitPeriod", INTERVAL
, NewCircuitPeriod
, "30 seconds"),
195 VAR("NamingAuthoritativeDirectory",BOOL
, NamingAuthoritativeDir
, "0"),
196 VAR("Nickname", STRING
, Nickname
, NULL
),
197 VAR("NoPublish", BOOL
, NoPublish
, "0"),
198 VAR("NodeFamily", LINELIST
, NodeFamilies
, NULL
),
199 VAR("NumCpus", UINT
, NumCpus
, "1"),
200 VAR("NumEntryGuards", UINT
, NumEntryGuards
, "3"),
201 VAR("ORListenAddress", LINELIST
, ORListenAddress
, NULL
),
202 VAR("ORPort", UINT
, ORPort
, "0"),
203 VAR("OutboundBindAddress", STRING
, OutboundBindAddress
, NULL
),
204 VAR("PathlenCoinWeight", DOUBLE
, PathlenCoinWeight
, "0.3"),
205 VAR("PidFile", STRING
, PidFile
, NULL
),
206 VAR("ProtocolWarnings", BOOL
, ProtocolWarnings
, "0"),
207 VAR("PublishServerDescriptor",BOOL
, PublishServerDescriptor
,"1"),
208 VAR("PublishHidServDescriptors",BOOL
,PublishHidServDescriptors
, "1"),
209 VAR("ReachableAddresses", LINELIST
, ReachableAddresses
, NULL
),
210 VAR("ReachableDirAddresses",LINELIST
,ReachableDirAddresses
,NULL
),
211 VAR("ReachableORAddresses",LINELIST
, ReachableORAddresses
, NULL
),
212 VAR("RecommendedVersions", LINELIST
, RecommendedVersions
, NULL
),
213 VAR("RecommendedClientVersions", LINELIST
, RecommendedClientVersions
, NULL
),
214 VAR("RecommendedServerVersions", LINELIST
, RecommendedServerVersions
, NULL
),
215 VAR("RedirectExit", LINELIST
, RedirectExit
, NULL
),
216 VAR("RendExcludeNodes", STRING
, RendExcludeNodes
, NULL
),
217 VAR("RendNodes", STRING
, RendNodes
, NULL
),
218 VAR("RendPostPeriod", INTERVAL
, RendPostPeriod
, "1 hour"),
219 VAR("RephistTrackTime", INTERVAL
, RephistTrackTime
, "24 hours"),
220 OBSOLETE("RouterFile"),
221 VAR("RunAsDaemon", BOOL
, RunAsDaemon
, "0"),
222 VAR("RunTesting", BOOL
, RunTesting
, "0"),
223 VAR("SafeLogging", BOOL
, SafeLogging
, "1"),
224 VAR("SafeSocks", BOOL
, SafeSocks
, "0"),
225 VAR("ShutdownWaitLength", INTERVAL
, ShutdownWaitLength
, "30 seconds"),
226 VAR("SocksListenAddress", LINELIST
, SocksListenAddress
, NULL
),
227 VAR("SocksPolicy", LINELIST
, SocksPolicy
, NULL
),
228 VAR("SocksPort", UINT
, SocksPort
, "9050"),
229 VAR("SocksTimeout", INTERVAL
, SocksTimeout
, "2 minutes"),
230 /* if StatusFetchPeriod is 0, see get_status_fetch_period() in main.c */
231 VAR("StatusFetchPeriod", INTERVAL
, StatusFetchPeriod
, "0 seconds"),
232 VAR("StrictEntryNodes", BOOL
, StrictEntryNodes
, "0"),
233 VAR("StrictExitNodes", BOOL
, StrictExitNodes
, "0"),
234 VAR("SysLog", LINELIST_S
, OldLogOptions
, NULL
),
235 VAR("TestSocks", BOOL
, TestSocks
, "0"),
236 VAR("TrackHostExits", CSV
, TrackHostExits
, NULL
),
237 VAR("TrackHostExitsExpire",INTERVAL
, TrackHostExitsExpire
, "30 minutes"),
238 OBSOLETE("TrafficShaping"),
239 VAR("UseEntryGuards", BOOL
, UseEntryGuards
, "1"),
240 VAR("User", STRING
, User
, NULL
),
241 VAR("V1AuthoritativeDirectory",BOOL
, V1AuthoritativeDir
, "0"),
242 VAR("VersioningAuthoritativeDirectory",BOOL
,VersioningAuthoritativeDir
, "0"),
243 VAR("VirtualAddrNetwork", STRING
, VirtualAddrNetwork
, "127.192.0.0/10"),
244 VAR("__LeaveStreamsUnattached", BOOL
,LeaveStreamsUnattached
, "0"),
245 { NULL
, CONFIG_TYPE_OBSOLETE
, 0, NULL
}
249 #define VAR(name,conftype,member,initvalue) \
250 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_state_t, member), \
252 static config_var_t _state_vars
[] = {
253 VAR("AccountingBytesReadInInterval", MEMUNIT
,
254 AccountingBytesReadInInterval
, NULL
),
255 VAR("AccountingBytesWrittenInInterval", MEMUNIT
,
256 AccountingBytesWrittenInInterval
, NULL
),
257 VAR("AccountingExpectedUsage", MEMUNIT
, AccountingExpectedUsage
, NULL
),
258 VAR("AccountingIntervalStart", ISOTIME
, AccountingIntervalStart
, NULL
),
259 VAR("AccountingSecondsActive", INTERVAL
, AccountingSecondsActive
, NULL
),
260 VAR("EntryGuard", LINELIST_S
, EntryGuards
, NULL
),
261 VAR("EntryGuardDownSince", LINELIST_S
, EntryGuards
, NULL
),
262 VAR("EntryGuardUnlistedSince", LINELIST_S
, EntryGuards
, NULL
),
263 VAR("EntryGuards", LINELIST_V
, EntryGuards
, NULL
),
265 VAR("BWHistoryReadEnds", ISOTIME
, BWHistoryReadEnds
, NULL
),
266 VAR("BWHistoryReadInterval", UINT
, BWHistoryReadInterval
, NULL
),
267 VAR("BWHistoryReadValues", CSV
, BWHistoryReadValues
, NULL
),
268 VAR("BWHistoryWriteEnds", ISOTIME
, BWHistoryWriteEnds
, NULL
),
269 VAR("BWHistoryWriteInterval", UINT
, BWHistoryWriteInterval
, NULL
),
270 VAR("BWHistoryWriteValues", CSV
, BWHistoryWriteValues
, NULL
),
272 VAR("TorVersion", STRING
, TorVersion
, NULL
),
274 VAR("LastWritten", ISOTIME
, LastWritten
, NULL
),
276 { NULL
, CONFIG_TYPE_OBSOLETE
, 0, NULL
}
282 /** Represents an English description of a configuration variable; used when
283 * generating configuration file comments. */
284 typedef struct config_var_description_t
{
286 const char *description
;
287 } config_var_description_t
;
289 static config_var_description_t options_description
[] = {
290 { "Address", "The advertised (external) address we should use." },
291 // { "AccountingStart", ""},
295 static config_var_description_t state_description
[] = {
296 { "AccountingBytesReadInInterval",
297 "How many bytes have we read in this accounting period?" },
298 { "AccountingBytesWrittenInInterval",
299 "How many bytes have we written in this accounting period?" },
300 { "AccountingExpectedUsage",
301 "How many bytes did we expect to use per minute? (0 for no estimate.)" },
302 { "AccountingIntervalStart", "When did this accounting period begin?" },
303 { "AccountingSecondsActive", "How long have we been awake in this period?" },
305 { "BWHistoryReadEnds", "When does the last-recorded read-interval end?" },
306 { "BWHistoryReadInterval", "How long is each read-interval (in seconds)?" },
307 { "BWHistoryReadValues", "Number of bytes read in each interval." },
308 { "BWHistoryWriteEnds", "When does the last-recorded write-interval end?" },
309 { "BWHistoryWriteInterval", "How long is each write-interval (in seconds)?"},
310 { "BWHistoryWriteValues", "Number of bytes written in each interval." },
312 { "EntryGuard", "One of the nodes we have chosen as a fixed entry" },
313 { "EntryGuardDownSince",
314 "The last entry guard has been down since this time." },
315 { "EntryGuardUnlistedSince",
316 "The last entry guard has been unlisted since this time." },
317 { "LastWritten", "When was this state file last regenerated?" },
319 { "TorVersion", "Which version of Tor generated this state file?" },
323 typedef int (*validate_fn_t
)(void*,void*,int,char**);
325 /** Information on the keys, value types, key-to-struct-member mappings,
326 * variable descriptions, validation functions, and abbreviations for a
327 * configuration or storage format. */
332 config_abbrev_t
*abbrevs
;
334 validate_fn_t validate_fn
;
335 config_var_description_t
*descriptions
;
336 /** If present, extra is a LINELIST variable for unrecognized
337 * lines. Otherwise, unrecognized lines are an error. */
341 #define CHECK(fmt, cfg) do { \
342 tor_assert(fmt && cfg); \
343 tor_assert((fmt)->magic == \
344 *(uint32_t*)STRUCT_VAR_P(cfg,fmt->magic_offset)); \
347 static void config_line_append(config_line_t
**lst
,
348 const char *key
, const char *val
);
349 static void option_clear(config_format_t
*fmt
, or_options_t
*options
,
351 static void option_reset(config_format_t
*fmt
, or_options_t
*options
,
352 config_var_t
*var
, int use_defaults
);
353 static void config_free(config_format_t
*fmt
, void *options
);
354 static int option_is_same(config_format_t
*fmt
,
355 or_options_t
*o1
, or_options_t
*o2
,
357 static or_options_t
*options_dup(config_format_t
*fmt
, or_options_t
*old
);
358 static int options_validate(or_options_t
*old_options
, or_options_t
*options
,
359 int from_setconf
, char **msg
);
360 static int options_act_reversible(or_options_t
*old_options
, char **msg
);
361 static int options_act(or_options_t
*old_options
);
362 static int options_transition_allowed(or_options_t
*old
, or_options_t
*new,
364 static int options_transition_affects_workers(or_options_t
*old_options
,
365 or_options_t
*new_options
);
366 static int options_transition_affects_descriptor(or_options_t
*old_options
,
367 or_options_t
*new_options
);
368 static int check_nickname_list(const char *lst
, const char *name
, char **msg
);
369 static void config_register_addressmaps(or_options_t
*options
);
371 static int parse_dir_server_line(const char *line
, int validate_only
);
372 static int parse_redirect_line(smartlist_t
*result
,
373 config_line_t
*line
, char **msg
);
374 static int parse_log_severity_range(const char *range
, int *min_out
,
376 static int convert_log_option(or_options_t
*options
,
377 config_line_t
*level_opt
,
378 config_line_t
*file_opt
, int isDaemon
);
379 static int add_single_log_option(or_options_t
*options
, int minSeverity
,
381 const char *type
, const char *fname
);
382 static int normalize_log_options(or_options_t
*options
);
383 static int validate_data_directory(or_options_t
*options
);
384 static int write_configuration_file(const char *fname
, or_options_t
*options
);
385 static config_line_t
*get_assigned_option(config_format_t
*fmt
,
386 or_options_t
*options
, const char *key
);
387 static void config_init(config_format_t
*fmt
, void *options
);
388 static int or_state_validate(or_state_t
*old_options
, or_state_t
*options
,
389 int from_setconf
, char **msg
);
391 static uint64_t config_parse_memunit(const char *s
, int *ok
);
392 static int config_parse_interval(const char *s
, int *ok
);
393 static void print_cvs_version(void);
394 static void init_libevent(void);
395 static int opt_streq(const char *s1
, const char *s2
);
396 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
397 static void check_libevent_version(const char *m
, const char *v
, int server
);
400 /*static*/ or_options_t
*options_new(void);
402 #define OR_OPTIONS_MAGIC 9090909
404 static config_format_t options_format
= {
405 sizeof(or_options_t
),
407 STRUCT_OFFSET(or_options_t
, _magic
),
410 (validate_fn_t
)options_validate
,
415 #define OR_STATE_MAGIC 0x57A73f57
417 static config_var_t state_extra_var
= {
418 "__extra", CONFIG_TYPE_LINELIST
, STRUCT_OFFSET(or_state_t
, ExtraLines
), NULL
421 static config_format_t state_format
= {
424 STRUCT_OFFSET(or_state_t
, _magic
),
427 (validate_fn_t
)or_state_validate
,
433 * Functions to read and write the global options pointer.
436 /** Command-line and config-file options. */
437 static or_options_t
*global_options
= NULL
;
438 /** Name of most recently read torrc file. */
439 static char *torrc_fname
= NULL
;
440 /** Persistent serialized state. */
441 static or_state_t
*global_state
= NULL
;
443 /** Allocate an empty configuration object of a given format type. */
445 config_alloc(config_format_t
*fmt
)
447 void *opts
= opts
= tor_malloc_zero(fmt
->size
);
448 *(uint32_t*)STRUCT_VAR_P(opts
, fmt
->magic_offset
) = fmt
->magic
;
453 /** Return the currently configured options. */
457 tor_assert(global_options
);
458 return global_options
;
461 /** Change the current global options to contain <b>new_val</b> instead of
462 * their current value; take action based on the new value; free the old value
466 set_options(or_options_t
*new_val
, char **msg
)
468 or_options_t
*old_options
= global_options
;
469 global_options
= new_val
;
470 /* Note that we pass the *old* options below, for comparison. It
471 * pulls the new options directly out of global_options. */
472 if (options_act_reversible(old_options
, msg
)<0) {
474 global_options
= old_options
;
477 if (options_act(old_options
) < 0) { /* acting on the options failed. die. */
479 "Acting on config options left us in a broken state. Dying.");
483 config_free(&options_format
, old_options
);
488 /** Release all memory and resources held by global configuration structures.
491 config_free_all(void)
493 if (global_options
) {
494 config_free(&options_format
, global_options
);
495 global_options
= NULL
;
498 config_free(&state_format
, global_state
);
501 tor_free(torrc_fname
);
504 /** If options->SafeLogging is on, return a not very useful string,
505 * else return address.
508 safe_str(const char *address
)
510 if (get_options()->SafeLogging
)
516 /** Equivalent to escaped(safe_str(address)) */
518 escaped_safe_str(const char *address
)
520 if (get_options()->SafeLogging
)
523 return escaped(address
);
526 /** Add the default directory servers directly into the trusted dir list. */
528 add_default_trusted_dirservers(void)
531 const char *dirservers
[] = {
532 "moria1 v1 18.244.0.188:9031 "
533 "FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441",
534 "moria2 v1 18.244.0.114:80 "
535 "719B E45D E224 B607 C537 07D0 E214 3E2D 423E 74CF",
536 "tor26 v1 86.59.21.38:80 "
537 "847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D",
538 "lefkada 140.247.60.64:80 "
539 "38D4 F5FC F7B1 0232 28B8 95EA 56ED E7D5 CCDC AF32",
540 "dizum 194.109.206.212:80 "
541 "7EA6 EAD6 FD83 083C 538F 4403 8BBF A077 587D D755",
544 for (i
=0; dirservers
[i
]; i
++)
545 parse_dir_server_line(dirservers
[i
], 0);
548 /** Fetch the active option list, and take actions based on it. All of the
549 * things we do should survive being done repeatedly. If present,
550 * <b>old_options</b> contains the previous value of the options.
552 * Return 0 if all goes well, return -1 if things went badly.
555 options_act_reversible(or_options_t
*old_options
, char **msg
)
557 smartlist_t
*new_listeners
= smartlist_create();
558 smartlist_t
*replaced_listeners
= smartlist_create();
559 static int libevent_initialized
= 0;
560 or_options_t
*options
= get_options();
561 int running_tor
= options
->command
== CMD_RUN_TOR
;
562 int set_conn_limit
= 0;
566 if (running_tor
&& options
->RunAsDaemon
) {
567 /* No need to roll back, since you can't change the value. */
571 /* Setuid/setgid as appropriate */
572 if (options
->User
|| options
->Group
) {
573 if (switch_id(options
->User
, options
->Group
) != 0) {
574 /* No need to roll back, since you can't change the value. */
575 *msg
= tor_strdup("Problem with User or Group value. "
576 "See logs for details.");
581 /* Set up libevent. */
582 if (running_tor
&& !libevent_initialized
) {
584 libevent_initialized
= 1;
587 /* Ensure data directory is private; create if possible. */
588 if (check_private_dir(options
->DataDirectory
, CPD_CREATE
)<0) {
590 int tmp
= tor_snprintf(buf
, sizeof(buf
),
591 "Couldn't access/create private data directory \"%s\"",
592 options
->DataDirectory
);
593 *msg
= tor_strdup(tmp
>= 0 ? buf
: "internal error");
595 /* No need to roll back, since you can't change the value. */
598 /* Bail out at this point if we're not going to be a client or server:
599 * we don't run Tor itself. */
600 if (options
->command
!= CMD_RUN_TOR
)
603 options
->_ConnLimit
=
604 set_max_file_descriptors((unsigned)options
->ConnLimit
, MAXCONNECTIONS
);
605 if (options
->_ConnLimit
< 0) {
606 *msg
= tor_strdup("Problem with ConnLimit value. See logs for details.");
611 if (retry_all_listeners(0, replaced_listeners
, new_listeners
) < 0) {
612 *msg
= tor_strdup("Failed to bind one of the listener ports.");
616 mark_logs_temp(); /* Close current logs once new logs are open. */
618 if (options_init_logs(options
, 0)<0) { /* Configure the log(s) */
619 *msg
= tor_strdup("Failed to init Log options. See logs for details.");
627 add_callback_log(LOG_ERR
, LOG_ERR
, control_event_logmsg
);
628 control_adjust_event_log_severity();
630 SMARTLIST_FOREACH(replaced_listeners
, connection_t
*, conn
,
632 log_notice(LD_NET
, "Closing old %s on %s:%d",
633 conn_type_to_string(conn
->type
), conn
->address
, conn
->port
);
634 connection_close_immediate(conn
);
635 connection_mark_for_close(conn
);
644 rollback_log_changes();
645 control_adjust_event_log_severity();
648 if (set_conn_limit
&& old_options
)
649 set_max_file_descriptors((unsigned)old_options
->ConnLimit
,MAXCONNECTIONS
);
651 SMARTLIST_FOREACH(new_listeners
, connection_t
*, conn
,
653 log_notice(LD_NET
, "Closing %s on %s:%d",
654 conn_type_to_string(conn
->type
), conn
->address
, conn
->port
);
655 connection_close_immediate(conn
);
656 connection_mark_for_close(conn
);
660 smartlist_free(new_listeners
);
661 smartlist_free(replaced_listeners
);
665 /** Fetch the active option list, and take actions based on it. All of the
666 * things we do should survive being done repeatedly. If present,
667 * <b>old_options</b> contains the previous value of the options.
669 * Return 0 if all goes well, return -1 if it's time to die.
671 * Note: We haven't moved all the "act on new configuration" logic
672 * here yet. Some is still in do_hup() and other places.
675 options_act(or_options_t
*old_options
)
680 or_options_t
*options
= get_options();
681 int running_tor
= options
->command
== CMD_RUN_TOR
;
684 clear_trusted_dir_servers();
685 if (options
->DirServers
) {
686 for (cl
= options
->DirServers
; cl
; cl
= cl
->next
) {
687 if (parse_dir_server_line(cl
->value
, 0)<0) {
689 "Bug: Previously validated DirServer line could not be added!");
694 add_default_trusted_dirservers();
697 if (running_tor
&& rend_config_services(options
, 0)<0) {
699 "Bug: Previously validated hidden services line could not be added!");
704 len
= strlen(options
->DataDirectory
)+32;
705 fn
= tor_malloc(len
);
706 tor_snprintf(fn
, len
, "%s/cached-status", options
->DataDirectory
);
707 if (check_private_dir(fn
, CPD_CREATE
) != 0) {
709 "Couldn't access/create private data directory \"%s\"", fn
);
716 /* Bail out at this point if we're not going to be a client or server:
717 * we want to not fork, and to log stuff to stderr. */
718 if (options
->command
!= CMD_RUN_TOR
)
727 smartlist_t
*sl
= smartlist_create();
729 for (cl
= options
->RedirectExit
; cl
; cl
= cl
->next
) {
730 if (parse_redirect_line(sl
, cl
, &errmsg
)<0)
731 log_warn(LD_CONFIG
, "%s", errmsg
);
735 set_exit_redirects(sl
);
738 /* Finish backgrounding the process */
739 if (running_tor
&& options
->RunAsDaemon
) {
740 /* We may be calling this for the n'th time (on SIGHUP), but it's safe. */
741 finish_daemon(options
->DataDirectory
);
744 /* Write our pid to the pid file. If we do not have write permissions we
745 * will log a warning */
746 if (running_tor
&& options
->PidFile
)
747 write_pidfile(options
->PidFile
);
749 /* Register addressmap directives */
750 config_register_addressmaps(options
);
751 parse_virtual_addr_network(options
->VirtualAddrNetwork
, 0, &msg
);
753 /* Update address policies. */
754 policies_parse_from_options(options
);
756 init_cookie_authentication(options
->CookieAuthentication
);
758 /* reload keys as needed for rendezvous services. */
759 if (rend_service_load_keys()<0) {
760 log_err(LD_GENERAL
,"Error loading rendezvous service keys");
764 /* Set up accounting */
765 if (accounting_parse_options(options
, 0)<0) {
766 log_err(LD_CONFIG
,"Error in accounting options");
769 if (accounting_is_enabled(options
))
770 configure_accounting(time(NULL
));
775 /* Check for transitions that need action. */
777 if (options
->UseEntryGuards
&& !old_options
->UseEntryGuards
) {
779 "Switching to entry guards; abandoning previous circuits");
780 circuit_mark_all_unused_circs();
781 circuit_expire_all_dirty_circs();
784 if (options_transition_affects_workers(old_options
, options
)) {
786 "Worker-related options changed. Rotating workers.");
787 if (server_mode(options
) && !server_mode(old_options
)) {
788 extern int has_completed_circuit
;
789 if (init_keys() < 0) {
790 log_err(LD_GENERAL
,"Error initializing keys; exiting");
793 server_has_changed_ip();
794 if (has_completed_circuit
)
795 inform_testing_reachability();
802 /* Check if we need to parse and add the EntryNodes config option. */
803 if (options
->EntryNodes
&&
805 !opt_streq(old_options
->EntryNodes
, options
->EntryNodes
)))
806 entry_nodes_should_be_added();
808 /* Since our options changed, we might need to regenerate and upload our
812 options_transition_affects_descriptor(old_options
, options
))
813 mark_my_descriptor_dirty();
819 * Functions to parse config options
822 /** If <b>option</b> is an official abbreviation for a longer option,
823 * return the longer option. Otherwise return <b>option</b>.
824 * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
825 * apply abbreviations that work for the config file and the command line.
826 * If <b>warn_obsolete</b> is set, warn about deprecated names. */
828 expand_abbrev(config_format_t
*fmt
, const char *option
, int command_line
,
834 for (i
=0; fmt
->abbrevs
[i
].abbreviated
; ++i
) {
835 /* Abbreviations are casei. */
836 if (!strcasecmp(option
,fmt
->abbrevs
[i
].abbreviated
) &&
837 (command_line
|| !fmt
->abbrevs
[i
].commandline_only
)) {
838 if (warn_obsolete
&& fmt
->abbrevs
[i
].warn
) {
840 "The configuration option '%s' is deprecated; "
842 fmt
->abbrevs
[i
].abbreviated
,
843 fmt
->abbrevs
[i
].full
);
845 return fmt
->abbrevs
[i
].full
;
851 /** Helper: Read a list of configuration options from the command line.
852 * If successful, put them in *<b>result</b> and return 0, and return
853 * -1 and leave *<b>result</b> alone. */
855 config_get_commandlines(int argc
, char **argv
, config_line_t
**result
)
857 config_line_t
*front
= NULL
;
858 config_line_t
**new = &front
;
863 if (!strcmp(argv
[i
],"-f") ||
864 !strcmp(argv
[i
],"--hash-password")) {
865 i
+= 2; /* command-line option with argument. ignore them. */
867 } else if (!strcmp(argv
[i
],"--list-fingerprint") ||
868 !strcmp(argv
[i
],"--verify-config")) {
869 i
+= 1; /* command-line option. ignore it. */
871 } else if (!strcmp(argv
[i
],"--nt-service")) {
876 log_warn(LD_CONFIG
,"Command-line option '%s' with no value. Failing.",
878 config_free_lines(front
);
882 *new = tor_malloc_zero(sizeof(config_line_t
));
888 (*new)->key
= tor_strdup(expand_abbrev(&options_format
, s
, 1, 1));
889 (*new)->value
= tor_strdup(argv
[i
+1]);
891 log(LOG_DEBUG
, LD_CONFIG
, "Commandline: parsed keyword '%s', value '%s'",
892 (*new)->key
, (*new)->value
);
894 new = &((*new)->next
);
901 /** Helper: allocate a new configuration option mapping 'key' to 'val',
902 * append it to *<b>lst</b>. */
904 config_line_append(config_line_t
**lst
,
908 config_line_t
*newline
;
910 newline
= tor_malloc(sizeof(config_line_t
));
911 newline
->key
= tor_strdup(key
);
912 newline
->value
= tor_strdup(val
);
913 newline
->next
= NULL
;
915 lst
= &((*lst
)->next
);
920 /** Helper: parse the config string and strdup into key/value
921 * strings. Set *result to the list, or NULL if parsing the string
922 * failed. Return 0 on success, -1 on failure. Warn and ignore any
923 * misformatted lines. */
925 config_get_lines(char *string
, config_line_t
**result
)
927 config_line_t
*list
= NULL
, **next
;
932 string
= parse_line_from_str(string
, &k
, &v
);
934 config_free_lines(list
);
938 /* This list can get long, so we keep a pointer to the end of it
939 * rather than using config_line_append over and over and getting n^2
940 * performance. This is the only really long list. */
941 *next
= tor_malloc(sizeof(config_line_t
));
942 (*next
)->key
= tor_strdup(k
);
943 (*next
)->value
= tor_strdup(v
);
944 (*next
)->next
= NULL
;
945 next
= &((*next
)->next
);
954 * Free all the configuration lines on the linked list <b>front</b>.
957 config_free_lines(config_line_t
*front
)
966 tor_free(tmp
->value
);
971 /** Return the description for a given configuration variable, or NULL if no
972 * description exists. */
974 config_find_description(config_format_t
*fmt
, const char *name
)
977 for (i
=0; fmt
->descriptions
[i
].name
; ++i
) {
978 if (!strcasecmp(name
, fmt
->descriptions
[i
].name
))
979 return fmt
->descriptions
[i
].description
;
984 /** If <b>key</b> is a configuration option, return the corresponding
985 * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
986 * warn, and return the corresponding config_var_t. Otherwise return NULL.
988 static config_var_t
*
989 config_find_option(config_format_t
*fmt
, const char *key
)
992 size_t keylen
= strlen(key
);
994 return NULL
; /* if they say "--" on the commandline, it's not an option */
995 /* First, check for an exact (case-insensitive) match */
996 for (i
=0; fmt
->vars
[i
].name
; ++i
) {
997 if (!strcasecmp(key
, fmt
->vars
[i
].name
)) {
998 return &fmt
->vars
[i
];
1001 /* If none, check for an abbreviated match */
1002 for (i
=0; fmt
->vars
[i
].name
; ++i
) {
1003 if (!strncasecmp(key
, fmt
->vars
[i
].name
, keylen
)) {
1004 log_warn(LD_CONFIG
, "The abbreviation '%s' is deprecated. "
1005 "Please use '%s' instead",
1006 key
, fmt
->vars
[i
].name
);
1007 return &fmt
->vars
[i
];
1010 /* Okay, unrecognized option */
1015 * Functions to assign config options.
1018 /** <b>c</b>-\>key is known to be a real key. Update <b>options</b>
1019 * with <b>c</b>-\>value and return 0, or return -1 if bad value.
1021 * Called from config_assign_line() and option_reset().
1024 config_assign_value(config_format_t
*fmt
, or_options_t
*options
,
1025 config_line_t
*c
, char **msg
)
1032 CHECK(fmt
, options
);
1034 var
= config_find_option(fmt
, c
->key
);
1037 lvalue
= STRUCT_VAR_P(options
, var
->var_offset
);
1039 switch (var
->type
) {
1041 case CONFIG_TYPE_UINT
:
1042 i
= tor_parse_long(c
->value
, 10, 0, INT_MAX
, &ok
, NULL
);
1044 r
= tor_snprintf(buf
, sizeof(buf
),
1045 "Int keyword '%s %s' is malformed or out of bounds.",
1047 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
1053 case CONFIG_TYPE_INTERVAL
: {
1054 i
= config_parse_interval(c
->value
, &ok
);
1056 r
= tor_snprintf(buf
, sizeof(buf
),
1057 "Interval '%s %s' is malformed or out of bounds.",
1059 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
1066 case CONFIG_TYPE_MEMUNIT
: {
1067 uint64_t u64
= config_parse_memunit(c
->value
, &ok
);
1069 r
= tor_snprintf(buf
, sizeof(buf
),
1070 "Value '%s %s' is malformed or out of bounds.",
1072 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
1075 *(uint64_t *)lvalue
= u64
;
1079 case CONFIG_TYPE_BOOL
:
1080 i
= tor_parse_long(c
->value
, 10, 0, 1, &ok
, NULL
);
1082 r
= tor_snprintf(buf
, sizeof(buf
),
1083 "Boolean '%s %s' expects 0 or 1.",
1085 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
1091 case CONFIG_TYPE_STRING
:
1092 tor_free(*(char **)lvalue
);
1093 *(char **)lvalue
= tor_strdup(c
->value
);
1096 case CONFIG_TYPE_DOUBLE
:
1097 *(double *)lvalue
= atof(c
->value
);
1100 case CONFIG_TYPE_ISOTIME
:
1101 if (parse_iso_time(c
->value
, (time_t *)lvalue
)) {
1102 r
= tor_snprintf(buf
, sizeof(buf
),
1103 "Invalid time '%s' for keyword '%s'", c
->value
, c
->key
);
1104 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
1109 case CONFIG_TYPE_CSV
:
1110 if (*(smartlist_t
**)lvalue
) {
1111 SMARTLIST_FOREACH(*(smartlist_t
**)lvalue
, char *, cp
, tor_free(cp
));
1112 smartlist_clear(*(smartlist_t
**)lvalue
);
1114 *(smartlist_t
**)lvalue
= smartlist_create();
1117 smartlist_split_string(*(smartlist_t
**)lvalue
, c
->value
, ",",
1118 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 0);
1121 case CONFIG_TYPE_LINELIST
:
1122 case CONFIG_TYPE_LINELIST_S
:
1123 config_line_append((config_line_t
**)lvalue
, c
->key
, c
->value
);
1126 case CONFIG_TYPE_OBSOLETE
:
1127 log_warn(LD_CONFIG
, "Skipping obsolete configuration option '%s'", c
->key
);
1129 case CONFIG_TYPE_LINELIST_V
:
1130 r
= tor_snprintf(buf
, sizeof(buf
),
1131 "You may not provide a value for virtual option '%s'", c
->key
);
1132 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
1141 /** If <b>c</b> is a syntactically valid configuration line, update
1142 * <b>options</b> with its value and return 0. Otherwise return -1 for bad
1143 * key, -2 for bad value.
1145 * If <b>clear_first</b> is set, clear the value first. Then if
1146 * <b>use_defaults</b> is set, set the value to the default.
1148 * Called from config_assign().
1151 config_assign_line(config_format_t
*fmt
, or_options_t
*options
,
1152 config_line_t
*c
, int use_defaults
,
1153 int clear_first
, char **msg
)
1157 CHECK(fmt
, options
);
1159 var
= config_find_option(fmt
, c
->key
);
1162 void *lvalue
= STRUCT_VAR_P(options
, fmt
->extra
->var_offset
);
1164 "Found unrecognized option '%s'; saving it.", c
->key
);
1165 config_line_append((config_line_t
**)lvalue
, c
->key
, c
->value
);
1169 int tmp
= tor_snprintf(buf
, sizeof(buf
),
1170 "Unknown option '%s'. Failing.", c
->key
);
1171 *msg
= tor_strdup(tmp
>= 0 ? buf
: "internal error");
1175 /* Put keyword into canonical case. */
1176 if (strcmp(var
->name
, c
->key
)) {
1178 c
->key
= tor_strdup(var
->name
);
1181 if (!strlen(c
->value
)) {
1182 /* reset or clear it, then return */
1184 if (var
->type
== CONFIG_TYPE_LINELIST
||
1185 var
->type
== CONFIG_TYPE_LINELIST_S
) {
1186 /* We got an empty linelist from the torrc or commandline.
1187 As a special case, call this an error. Warn and ignore. */
1189 "Linelist option '%s' has no value. Skipping.", c
->key
);
1190 } else { /* not already cleared */
1191 option_reset(fmt
, options
, var
, use_defaults
);
1197 if (config_assign_value(fmt
, options
, c
, msg
) < 0)
1202 /** Restore the option named <b>key</b> in options to its default value.
1203 * Called from config_assign(). */
1205 config_reset_line(config_format_t
*fmt
, or_options_t
*options
,
1206 const char *key
, int use_defaults
)
1210 CHECK(fmt
, options
);
1212 var
= config_find_option(fmt
, key
);
1214 return; /* give error on next pass. */
1216 option_reset(fmt
, options
, var
, use_defaults
);
1219 /** Return true iff key is a valid configuration option. */
1221 option_is_recognized(const char *key
)
1223 config_var_t
*var
= config_find_option(&options_format
, key
);
1224 return (var
!= NULL
);
1227 /** Return the canonical name of a configuration option. */
1229 option_get_canonical_name(const char *key
)
1231 config_var_t
*var
= config_find_option(&options_format
, key
);
1235 /** Return a canonicalized list of the options assigned for key.
1238 option_get_assignment(or_options_t
*options
, const char *key
)
1240 return get_assigned_option(&options_format
, options
, key
);
1243 static config_line_t
*
1244 config_lines_dup(const config_line_t
*inp
)
1246 config_line_t
*result
= NULL
;
1247 config_line_t
**next_out
= &result
;
1249 *next_out
= tor_malloc(sizeof(config_line_t
));
1250 (*next_out
)->key
= tor_strdup(inp
->key
);
1251 (*next_out
)->value
= tor_strdup(inp
->value
);
1253 next_out
= &((*next_out
)->next
);
1259 static config_line_t
*
1260 get_assigned_option(config_format_t
*fmt
, or_options_t
*options
,
1266 config_line_t
*result
;
1267 tor_assert(options
&& key
);
1269 CHECK(fmt
, options
);
1271 var
= config_find_option(fmt
, key
);
1273 log_warn(LD_CONFIG
, "Unknown option '%s'. Failing.", key
);
1275 } else if (var
->type
== CONFIG_TYPE_LINELIST_S
) {
1277 "Can't return context-sensitive '%s' on its own", key
);
1280 value
= STRUCT_VAR_P(options
, var
->var_offset
);
1282 if (var
->type
== CONFIG_TYPE_LINELIST
||
1283 var
->type
== CONFIG_TYPE_LINELIST_V
) {
1284 /* Linelist requires special handling: we just copy and return it. */
1285 return config_lines_dup(*(const config_line_t
**)value
);
1288 result
= tor_malloc_zero(sizeof(config_line_t
));
1289 result
->key
= tor_strdup(var
->name
);
1292 case CONFIG_TYPE_STRING
:
1293 if (*(char**)value
) {
1294 result
->value
= tor_strdup(*(char**)value
);
1296 tor_free(result
->key
);
1301 case CONFIG_TYPE_ISOTIME
:
1302 if (*(time_t*)value
) {
1303 result
->value
= tor_malloc(ISO_TIME_LEN
+1);
1304 format_iso_time(result
->value
, *(time_t*)value
);
1306 tor_free(result
->key
);
1310 case CONFIG_TYPE_INTERVAL
:
1311 case CONFIG_TYPE_UINT
:
1312 /* This means every or_options_t uint or bool element
1313 * needs to be an int. Not, say, a uint16_t or char. */
1314 tor_snprintf(buf
, sizeof(buf
), "%d", *(int*)value
);
1315 result
->value
= tor_strdup(buf
);
1317 case CONFIG_TYPE_MEMUNIT
:
1318 tor_snprintf(buf
, sizeof(buf
), U64_FORMAT
,
1319 U64_PRINTF_ARG(*(uint64_t*)value
));
1320 result
->value
= tor_strdup(buf
);
1322 case CONFIG_TYPE_DOUBLE
:
1323 tor_snprintf(buf
, sizeof(buf
), "%f", *(double*)value
);
1324 result
->value
= tor_strdup(buf
);
1326 case CONFIG_TYPE_BOOL
:
1327 result
->value
= tor_strdup(*(int*)value
? "1" : "0");
1329 case CONFIG_TYPE_CSV
:
1330 if (*(smartlist_t
**)value
)
1332 smartlist_join_strings(*(smartlist_t
**)value
, ",", 0, NULL
);
1334 result
->value
= tor_strdup("");
1336 case CONFIG_TYPE_OBSOLETE
:
1338 "You asked me for the value of an obsolete config option '%s'.",
1340 tor_free(result
->key
);
1344 tor_free(result
->key
);
1346 log_warn(LD_BUG
,"Bug: unknown type %d for known key '%s'",
1354 /** Iterate through the linked list of requested options <b>list</b>.
1355 * For each item, convert as appropriate and assign to <b>options</b>.
1356 * If an item is unrecognized, set *msg and return -1 immediately,
1357 * else return 0 for success.
1359 * If <b>clear_first</b>, interpret config options as replacing (not
1360 * extending) their previous values. If <b>clear_first</b> is set,
1361 * then <b>use_defaults</b> to decide if you set to defaults after
1362 * clearing, or make the value 0 or NULL.
1364 * Here are the use cases:
1365 * 1. A non-empty AllowInvalid line in your torrc. Appends to current
1366 * if linelist, replaces current if csv.
1367 * 2. An empty AllowInvalid line in your torrc. Should clear it.
1368 * 3. "RESETCONF AllowInvalid" sets it to default.
1369 * 4. "SETCONF AllowInvalid" makes it NULL.
1370 * 5. "SETCONF AllowInvalid=foo" clears it and sets it to "foo".
1372 * Use_defaults Clear_first
1374 * 1 0 undefined, don't use
1375 * 0 1 "set to null first"
1376 * 1 1 "set to defaults first"
1377 * Return 0 on success, -1 on bad key, -2 on bad value.
1379 * As an additional special case, if a LINELIST config option has
1380 * no value and clear_first is 0, then warn and ignore it.
1384 There are three call cases for config_assign() currently.
1386 Case one: Torrc entry
1387 options_init_from_torrc() calls config_assign(0, 0)
1388 calls config_assign_line(0, 0).
1389 if value is empty, calls option_reset(0) and returns.
1390 calls config_assign_value(), appends.
1393 options_trial_assign() calls config_assign(0, 1)
1394 calls config_reset_line(0)
1395 calls option_reset(0)
1396 calls option_clear().
1397 calls config_assign_line(0, 1).
1398 if value is empty, returns.
1399 calls config_assign_value(), appends.
1401 Case three: resetconf
1402 options_trial_assign() calls config_assign(1, 1)
1403 calls config_reset_line(1)
1404 calls option_reset(1)
1405 calls option_clear().
1406 calls config_assign_value(default)
1407 calls config_assign_line(1, 1).
1411 config_assign(config_format_t
*fmt
, void *options
, config_line_t
*list
,
1412 int use_defaults
, int clear_first
, char **msg
)
1416 CHECK(fmt
, options
);
1418 /* pass 1: normalize keys */
1419 for (p
= list
; p
; p
= p
->next
) {
1420 const char *full
= expand_abbrev(fmt
, p
->key
, 0, 1);
1421 if (strcmp(full
,p
->key
)) {
1423 p
->key
= tor_strdup(full
);
1427 /* pass 2: if we're reading from a resetting source, clear all
1428 * mentioned config options, and maybe set to their defaults. */
1430 for (p
= list
; p
; p
= p
->next
)
1431 config_reset_line(fmt
, options
, p
->key
, use_defaults
);
1434 /* pass 3: assign. */
1437 if ((r
=config_assign_line(fmt
, options
, list
, use_defaults
,
1445 /** Try assigning <b>list</b> to the global options. You do this by duping
1446 * options, assigning list to the new one, then validating it. If it's
1447 * ok, then throw out the old one and stick with the new one. Else,
1448 * revert to old and return failure. Return 0 on success, -1 on bad
1449 * keys, -2 on bad values, -3 on bad transition, and -4 on failed-to-set.
1451 * If not success, point *<b>msg</b> to a newly allocated string describing
1455 options_trial_assign(config_line_t
*list
, int use_defaults
,
1456 int clear_first
, char **msg
)
1459 or_options_t
*trial_options
= options_dup(&options_format
, get_options());
1461 if ((r
=config_assign(&options_format
, trial_options
,
1462 list
, use_defaults
, clear_first
, msg
)) < 0) {
1463 config_free(&options_format
, trial_options
);
1467 if (options_validate(get_options(), trial_options
, 1, msg
) < 0) {
1468 config_free(&options_format
, trial_options
);
1472 if (options_transition_allowed(get_options(), trial_options
, msg
) < 0) {
1473 config_free(&options_format
, trial_options
);
1477 if (set_options(trial_options
, msg
)<0) {
1478 config_free(&options_format
, trial_options
);
1482 /* we liked it. put it in place. */
1486 /** Reset config option <b>var</b> to 0, 0.0, NULL, or the equivalent.
1487 * Called from option_reset() and config_free(). */
1489 option_clear(config_format_t
*fmt
, or_options_t
*options
, config_var_t
*var
)
1491 void *lvalue
= STRUCT_VAR_P(options
, var
->var_offset
);
1492 switch (var
->type
) {
1493 case CONFIG_TYPE_STRING
:
1494 tor_free(*(char**)lvalue
);
1496 case CONFIG_TYPE_DOUBLE
:
1497 *(double*)lvalue
= 0.0;
1499 case CONFIG_TYPE_ISOTIME
:
1500 *(time_t*)lvalue
= 0;
1501 case CONFIG_TYPE_INTERVAL
:
1502 case CONFIG_TYPE_UINT
:
1503 case CONFIG_TYPE_BOOL
:
1506 case CONFIG_TYPE_MEMUNIT
:
1507 *(uint64_t*)lvalue
= 0;
1509 case CONFIG_TYPE_CSV
:
1510 if (*(smartlist_t
**)lvalue
) {
1511 SMARTLIST_FOREACH(*(smartlist_t
**)lvalue
, char *, cp
, tor_free(cp
));
1512 smartlist_free(*(smartlist_t
**)lvalue
);
1513 *(smartlist_t
**)lvalue
= NULL
;
1516 case CONFIG_TYPE_LINELIST
:
1517 case CONFIG_TYPE_LINELIST_S
:
1518 config_free_lines(*(config_line_t
**)lvalue
);
1519 *(config_line_t
**)lvalue
= NULL
;
1521 case CONFIG_TYPE_LINELIST_V
:
1522 /* handled by linelist_s. */
1524 case CONFIG_TYPE_OBSOLETE
:
1529 /** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
1530 * <b>use_defaults</b>, set it to its default value.
1531 * Called by config_init() and option_reset_line() and option_assign_line(). */
1533 option_reset(config_format_t
*fmt
, or_options_t
*options
,
1534 config_var_t
*var
, int use_defaults
)
1539 CHECK(fmt
, options
);
1540 option_clear(fmt
, options
, var
); /* clear it first */
1542 return; /* all done */
1543 lvalue
= STRUCT_VAR_P(options
, var
->var_offset
);
1544 if (var
->initvalue
) {
1545 c
= tor_malloc_zero(sizeof(config_line_t
));
1546 c
->key
= tor_strdup(var
->name
);
1547 c
->value
= tor_strdup(var
->initvalue
);
1548 if (config_assign_value(fmt
, options
, c
, &msg
) < 0) {
1549 log_warn(LD_BUG
, "Failed to assign default: %s", msg
);
1550 tor_free(msg
); /* if this happens it's a bug */
1552 config_free_lines(c
);
1556 /** Print a usage message for tor. */
1561 "Copyright 2001-2005 Roger Dingledine, Nick Mathewson.\n\n"
1562 "tor -f <torrc> [args]\n"
1563 "See man page for options, or http://tor.eff.org/ for documentation.\n");
1567 * Based on <b>options-\>Address</b>, guess our public IP address and put it
1568 * (in host order) into *<b>addr_out</b>. If <b>hostname_out</b> is provided,
1569 * set *<b>hostname_out</b> to a new string holding the hostname we used to
1570 * get the address. Return 0 if all is well, or -1 if we can't find a suitable
1571 * public IP address.
1574 resolve_my_address(or_options_t
*options
, uint32_t *addr_out
,
1575 char **hostname_out
)
1578 struct hostent
*rent
;
1581 int explicit_hostname
=1;
1582 char tmpbuf
[INET_NTOA_BUF_LEN
];
1583 static uint32_t old_addr
=0;
1584 const char *address
= options
->Address
;
1586 tor_assert(addr_out
);
1588 if (address
&& *address
) {
1589 strlcpy(hostname
, address
, sizeof(hostname
));
1590 } else { /* then we need to guess our address */
1591 explicit_ip
= 0; /* it's implicit */
1592 explicit_hostname
= 0; /* it's implicit */
1594 if (gethostname(hostname
, sizeof(hostname
)) < 0) {
1595 log_warn(LD_NET
,"Error obtaining local hostname");
1598 log_debug(LD_CONFIG
,"Guessed local host name as '%s'",hostname
);
1601 /* now we know hostname. resolve it and keep only the IP */
1603 if (tor_inet_aton(hostname
, &in
) == 0) {
1604 /* then we have to resolve it */
1606 rent
= (struct hostent
*)gethostbyname(hostname
);
1608 uint32_t interface_ip
;
1610 if (explicit_hostname
) {
1611 log_warn(LD_CONFIG
,"Could not resolve local Address '%s'. Failing.",
1615 log_notice(LD_CONFIG
, "Could not resolve guessed local hostname '%s'. "
1616 "Trying something else.", hostname
);
1617 if (get_interface_address(&interface_ip
)) {
1618 log_warn(LD_CONFIG
, "Could not get local interface IP address. "
1622 in
.s_addr
= htonl(interface_ip
);
1623 tor_inet_ntoa(&in
,tmpbuf
,sizeof(tmpbuf
));
1624 log_notice(LD_CONFIG
, "Learned IP address '%s' for local interface."
1625 " Using that.", tmpbuf
);
1626 strlcpy(hostname
, "<guessed from interfaces>", sizeof(hostname
));
1628 tor_assert(rent
->h_length
== 4);
1629 memcpy(&in
.s_addr
, rent
->h_addr
, rent
->h_length
);
1631 if (!explicit_hostname
&&
1632 is_internal_IP(ntohl(in
.s_addr
), 0)) {
1633 uint32_t interface_ip
;
1635 tor_inet_ntoa(&in
,tmpbuf
,sizeof(tmpbuf
));
1636 log_notice(LD_CONFIG
, "Guessed local hostname '%s' resolves to a "
1637 "private IP address (%s). Trying something else.", hostname
,
1640 if (get_interface_address(&interface_ip
)) {
1641 log_warn(LD_CONFIG
, "Could not get local interface IP address. "
1643 } else if (is_internal_IP(interface_ip
, 0)) {
1645 in2
.s_addr
= htonl(interface_ip
);
1646 tor_inet_ntoa(&in2
,tmpbuf
,sizeof(tmpbuf
));
1647 log_notice(LD_CONFIG
, "Interface IP '%s' is a private address "
1648 "too. Ignoring.", tmpbuf
);
1650 in
.s_addr
= htonl(interface_ip
);
1651 tor_inet_ntoa(&in
,tmpbuf
,sizeof(tmpbuf
));
1652 log_notice(LD_CONFIG
, "Learned IP address '%s' for local interface."
1653 " Using that.", tmpbuf
);
1654 strlcpy(hostname
, "<guessed from interfaces>", sizeof(hostname
));
1660 tor_inet_ntoa(&in
,tmpbuf
,sizeof(tmpbuf
));
1661 if (is_internal_IP(ntohl(in
.s_addr
), 0) &&
1662 options
->PublishServerDescriptor
) {
1663 /* make sure we're ok with publishing an internal IP */
1664 if (!options
->DirServers
) {
1665 /* if they are using the default dirservers, disallow internal IPs
1667 log_warn(LD_CONFIG
,"Address '%s' resolves to private IP '%s'. "
1668 "Tor servers that use the default DirServers must have public "
1674 /* even if they've set their own dirservers, require an explicit IP if
1675 * they're using an internal address. */
1676 log_warn(LD_CONFIG
,"Address '%s' resolves to private IP '%s'. Please "
1677 "set the Address config option to be the IP you want to use.",
1683 log_debug(LD_CONFIG
, "Resolved Address to '%s'.", tmpbuf
);
1684 *addr_out
= ntohl(in
.s_addr
);
1685 if (old_addr
&& old_addr
!= *addr_out
) {
1686 log_notice(LD_NET
, "Your IP seems to have changed. Updating.");
1687 server_has_changed_ip();
1689 old_addr
= *addr_out
;
1691 *hostname_out
= tor_strdup(hostname
);
1695 /** Called when we don't have a nickname set. Try to guess a good nickname
1696 * based on the hostname, and return it in a newly allocated string. If we
1697 * can't, return NULL and let the caller warn if it wants to. */
1699 get_default_nickname(void)
1701 char localhostname
[256];
1702 char *cp
, *out
, *outp
;
1704 if (gethostname(localhostname
, sizeof(localhostname
)) < 0)
1707 /* Put it in lowercase; stop at the first dot. */
1708 for (cp
= localhostname
; *cp
; ++cp
) {
1716 /* Strip invalid characters. */
1718 out
= outp
= tor_malloc(strlen(localhostname
) + 1);
1720 if (strchr(LEGAL_NICKNAME_CHARACTERS
, *cp
))
1727 /* Enforce length. */
1728 if (strlen(out
) > MAX_NICKNAME_LEN
)
1729 out
[MAX_NICKNAME_LEN
]='\0';
1734 /** Release storage held by <b>options</b> */
1736 config_free(config_format_t
*fmt
, void *options
)
1740 tor_assert(options
);
1742 for (i
=0; fmt
->vars
[i
].name
; ++i
)
1743 option_clear(fmt
, options
, &(fmt
->vars
[i
]));
1745 config_line_t
**linep
= STRUCT_VAR_P(options
, fmt
->extra
->var_offset
);
1746 config_free_lines(*linep
);
1752 /** Return true iff a and b contain identical keys and values in identical
1755 config_lines_eq(config_line_t
*a
, config_line_t
*b
)
1758 if (strcasecmp(a
->key
, b
->key
) || strcmp(a
->value
, b
->value
))
1768 /** Return true iff the option <b>var</b> has the same value in <b>o1</b>
1769 * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
1772 option_is_same(config_format_t
*fmt
,
1773 or_options_t
*o1
, or_options_t
*o2
, const char *name
)
1775 config_line_t
*c1
, *c2
;
1780 c1
= get_assigned_option(fmt
, o1
, name
);
1781 c2
= get_assigned_option(fmt
, o2
, name
);
1782 r
= config_lines_eq(c1
, c2
);
1783 config_free_lines(c1
);
1784 config_free_lines(c2
);
1788 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
1789 static or_options_t
*
1790 options_dup(config_format_t
*fmt
, or_options_t
*old
)
1792 or_options_t
*newopts
;
1794 config_line_t
*line
;
1796 newopts
= config_alloc(fmt
);
1797 for (i
=0; fmt
->vars
[i
].name
; ++i
) {
1798 if (fmt
->vars
[i
].type
== CONFIG_TYPE_LINELIST_S
)
1800 if (fmt
->vars
[i
].type
== CONFIG_TYPE_OBSOLETE
)
1802 line
= get_assigned_option(fmt
, old
, fmt
->vars
[i
].name
);
1805 if (config_assign(fmt
, newopts
, line
, 0, 0, &msg
) < 0) {
1806 log_err(LD_BUG
, "Bug: config_get_assigned_option() generated "
1807 "something we couldn't config_assign(): %s", msg
);
1812 config_free_lines(line
);
1817 /** Return a new empty or_options_t. Used for testing. */
1821 return config_alloc(&options_format
);
1824 /** Set <b>options</b> to hold reasonable defaults for most options.
1825 * Each option defaults to zero. */
1827 options_init(or_options_t
*options
)
1829 config_init(&options_format
, options
);
1832 /* Set all vars in the configuration object 'options' to their default
1835 config_init(config_format_t
*fmt
, void *options
)
1839 CHECK(fmt
, options
);
1841 for (i
=0; fmt
->vars
[i
].name
; ++i
) {
1842 var
= &fmt
->vars
[i
];
1843 if (!var
->initvalue
)
1844 continue; /* defaults to NULL or 0 */
1845 option_reset(fmt
, options
, var
, 1);
1849 /* Allocate and return a new string holding the written-out values of the vars
1850 * in 'options' If 'minimal', do not write out any default-valued vars. */
1852 config_dump(config_format_t
*fmt
, void *options
, int minimal
)
1854 smartlist_t
*elements
;
1855 or_options_t
*defaults
;
1856 config_line_t
*line
, *assigned
;
1862 defaults
= config_alloc(fmt
);
1863 config_init(fmt
, defaults
);
1865 /* XXX use a 1 here so we don't add a new log line while dumping */
1866 if (fmt
->validate_fn(NULL
,defaults
, 1, &msg
) < 0) {
1867 log_err(LD_BUG
, "Failed to validate default config.");
1872 elements
= smartlist_create();
1873 for (i
=0; fmt
->vars
[i
].name
; ++i
) {
1874 if (fmt
->vars
[i
].type
== CONFIG_TYPE_OBSOLETE
||
1875 fmt
->vars
[i
].type
== CONFIG_TYPE_LINELIST_S
)
1877 /* Don't save 'hidden' control variables. */
1878 if (!strcmpstart(fmt
->vars
[i
].name
, "__"))
1880 if (minimal
&& option_is_same(fmt
, options
, defaults
, fmt
->vars
[i
].name
))
1883 desc
= config_find_description(fmt
, fmt
->vars
[i
].name
);
1884 line
= assigned
= get_assigned_option(fmt
, options
, fmt
->vars
[i
].name
);
1887 /* Only dump the description if there's something to describe. */
1888 size_t len
= strlen(desc
)+8;
1889 char *tmp
= tor_malloc(len
);
1890 tor_snprintf(tmp
, len
, "# %s\n",desc
);
1891 smartlist_add(elements
, tmp
);
1894 for (; line
; line
= line
->next
) {
1895 size_t len
= strlen(line
->key
) + strlen(line
->value
) + 3;
1897 tmp
= tor_malloc(len
);
1898 if (tor_snprintf(tmp
, len
, "%s %s\n", line
->key
, line
->value
)<0) {
1899 log_err(LD_BUG
,"Internal error writing option value");
1902 smartlist_add(elements
, tmp
);
1904 config_free_lines(assigned
);
1908 line
= *(config_line_t
**)STRUCT_VAR_P(options
, fmt
->extra
->var_offset
);
1909 for (; line
; line
= line
->next
) {
1910 size_t len
= strlen(line
->key
) + strlen(line
->value
) + 3;
1912 tmp
= tor_malloc(len
);
1913 if (tor_snprintf(tmp
, len
, "%s %s\n", line
->key
, line
->value
)<0) {
1914 log_err(LD_BUG
,"Internal error writing option value");
1917 smartlist_add(elements
, tmp
);
1921 result
= smartlist_join_strings(elements
, "", 0, NULL
);
1922 SMARTLIST_FOREACH(elements
, char *, cp
, tor_free(cp
));
1923 smartlist_free(elements
);
1924 config_free(fmt
, defaults
);
1928 /** Return a string containing a possible configuration file that would give
1929 * the configuration in <b>options</b>. If <b>minimal</b> is true, do not
1930 * include options that are the same as Tor's defaults.
1933 options_dump(or_options_t
*options
, int minimal
)
1935 return config_dump(&options_format
, options
, minimal
);
1938 /* Return 0 if every element of sl is a string holding a decimal
1939 * representation of a port number, or if sl is NULL.
1940 * Otherwise set *msg and return -1. */
1942 validate_ports_csv(smartlist_t
*sl
, const char *name
, char **msg
)
1951 SMARTLIST_FOREACH(sl
, const char *, cp
,
1954 if (i
< 1 || i
> 65535) {
1955 int r
= tor_snprintf(buf
, sizeof(buf
),
1956 "Port '%s' out of range in %s", cp
, name
);
1957 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
1964 /** Lowest allowable value for DirFetchPeriod; if this is too low, clients can
1965 * overload the directory system. */
1966 #define MIN_DIR_FETCH_PERIOD (10*60)
1967 /** Lowest allowable value for RendPostPeriod; if this is too low, hidden
1968 * services can overload the directory system. */
1969 #define MIN_REND_POST_PERIOD (5*60)
1970 /** Lowest allowable value for StatusFetchPeriod; if this is too low, clients
1971 * can overload the directory system. */
1972 #define MIN_STATUS_FETCH_PERIOD (5*60)
1974 /** Highest allowable value for DirFetchPeriod, StatusFetchPeriod, and
1975 * RendPostPeriod. */
1976 #define MAX_DIR_PERIOD (MIN_ONION_KEY_LIFETIME/2)
1977 /** Highest allowable value for DirFetchPeriod for directory caches. */
1978 #define MAX_CACHE_DIR_FETCH_PERIOD (60*60)
1979 /** Highest allowable value for StatusFetchPeriod for directory caches. */
1980 #define MAX_CACHE_STATUS_FETCH_PERIOD (15*60)
1982 /** Return 0 if every setting in <b>options</b> is reasonable, and a
1983 * permissible transition from <b>old_options</b>. Else return -1.
1984 * Should have no side effects, except for normalizing the contents of
1987 * On error, tor_strdup an error explanation into *<b>msg</b>.
1990 * If <b>from_setconf</b>, we were called by the controller, and our
1991 * Log line should stay empty. If it's 0, then give us a default log
1992 * if there are no logs defined.
1995 options_validate(or_options_t
*old_options
, or_options_t
*options
,
1996 int from_setconf
, char **msg
)
2002 #define REJECT(arg) \
2003 do { *msg = tor_strdup(arg); return -1; } while (0)
2004 #define COMPLAIN(arg) do { log(LOG_WARN, LD_CONFIG, arg); } while (0)
2009 if (options
->ORPort
< 0 || options
->ORPort
> 65535)
2010 REJECT("ORPort option out of bounds.");
2012 uname
= get_uname();
2013 if (server_mode(options
) &&
2014 (!strcmpstart(uname
, "Windows 95") ||
2015 !strcmpstart(uname
, "Windows 98") ||
2016 !strcmpstart(uname
, "Windows Me"))) {
2017 log(LOG_WARN
, LD_CONFIG
, "Tor is running as a server, but you are "
2018 "running %s; this probably won't work. See "
2019 "http://wiki.noreply.org/noreply/TheOnionRouter/TorFAQ#ServerOS "
2020 "for details.", get_uname());
2023 if (options
->ORPort
== 0 && options
->ORListenAddress
!= NULL
)
2024 REJECT("ORPort must be defined if ORListenAddress is defined.");
2026 if (options
->DirPort
== 0 && options
->DirListenAddress
!= NULL
)
2027 REJECT("DirPort must be defined if DirListenAddress is defined.");
2029 if (options
->ControlPort
== 0 && options
->ControlListenAddress
!= NULL
)
2030 REJECT("ControlPort must be defined if ControlListenAddress is defined.");
2032 #if 0 /* don't complain, since a standard configuration does this! */
2033 if (options
->SocksPort
== 0 && options
->SocksListenAddress
!= NULL
)
2034 REJECT("SocksPort must be defined if SocksListenAddress is defined.");
2037 if (options
->SocksListenAddress
) {
2038 config_line_t
*line
= NULL
;
2039 char *address
= NULL
;
2040 for (line
= options
->SocksListenAddress
; line
; line
= line
->next
) {
2043 if (parse_addr_port(line
->value
, &address
, &addr
, &port
)<0)
2044 continue; /* We'll warn about this later. */
2045 if (!is_internal_IP(addr
, 1) &&
2046 (!old_options
|| !config_lines_eq(old_options
->SocksListenAddress
,
2047 options
->SocksListenAddress
))) {
2049 "You specified a public address '%s' for a SOCKS listener. Other "
2050 "people on the Internet might find your computer and use it as "
2051 "an open SOCKS proxy. Please don't allow this unless you have "
2052 "a good reason.", address
);
2058 if (validate_data_directory(options
)<0)
2059 REJECT("Invalid DataDirectory");
2061 if (options
->Nickname
== NULL
) {
2062 if (server_mode(options
)) {
2063 if (!(options
->Nickname
= get_default_nickname()))
2064 REJECT("Error obtaining local hostname");
2065 log_notice(LD_CONFIG
, "Choosing default nickname '%s'",
2069 if (!is_legal_nickname(options
->Nickname
)) {
2070 r
= tor_snprintf(buf
, sizeof(buf
),
2071 "Nickname '%s' is wrong length or contains illegal characters.",
2073 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
2078 if (server_mode(options
) && !options
->ContactInfo
)
2079 log(LOG_NOTICE
, LD_CONFIG
, "Your ContactInfo config option is not set. "
2080 "Please consider setting it, so we can contact you if your server is "
2081 "misconfigured or something else goes wrong.");
2083 if (normalize_log_options(options
))
2084 REJECT("Failed to normalize old Log options. See logs for details.");
2086 /* Special case on first boot if no Log options are given. */
2087 if (!options
->Logs
&& !from_setconf
)
2088 config_line_append(&options
->Logs
, "Log", "notice stdout");
2090 if (options_init_logs(options
, 1)<0) /* Validate the log(s) */
2091 REJECT("Failed to validate Log options. See logs for details.");
2093 if (options
->NoPublish
) {
2094 log(LOG_WARN
, LD_CONFIG
,
2095 "NoPublish is obsolete. Use PublishServerDescriptor instead.");
2096 options
->PublishServerDescriptor
= 0;
2099 if (server_mode(options
)) {
2100 /* confirm that our address isn't broken, so we can complain now */
2102 if (resolve_my_address(options
, &tmp
, NULL
) < 0)
2103 REJECT("Failed to resolve/guess local address. See logs for details.");
2107 if (options
->RunAsDaemon
&& torrc_fname
&& path_is_relative(torrc_fname
))
2108 REJECT("Can't use a relative path to torrc when RunAsDaemon is set.");
2111 if (options
->SocksPort
< 0 || options
->SocksPort
> 65535)
2112 REJECT("SocksPort option out of bounds.");
2114 if (options
->SocksPort
== 0 && options
->ORPort
== 0)
2115 REJECT("SocksPort and ORPort are both undefined? Quitting.");
2117 if (options
->ControlPort
< 0 || options
->ControlPort
> 65535)
2118 REJECT("ControlPort option out of bounds.");
2120 if (options
->DirPort
< 0 || options
->DirPort
> 65535)
2121 REJECT("DirPort option out of bounds.");
2123 if (options
->StrictExitNodes
&&
2124 (!options
->ExitNodes
|| !strlen(options
->ExitNodes
)) &&
2126 (old_options
->StrictExitNodes
!= options
->StrictExitNodes
) ||
2127 (!opt_streq(old_options
->ExitNodes
, options
->ExitNodes
))))
2128 COMPLAIN("StrictExitNodes set, but no ExitNodes listed.");
2130 if (options
->StrictEntryNodes
&&
2131 (!options
->EntryNodes
|| !strlen(options
->EntryNodes
)) &&
2133 (old_options
->StrictEntryNodes
!= options
->StrictEntryNodes
) ||
2134 (!opt_streq(old_options
->EntryNodes
, options
->EntryNodes
))))
2135 COMPLAIN("StrictEntryNodes set, but no EntryNodes listed.");
2137 if (options
->AuthoritativeDir
) {
2138 if (!options
->ContactInfo
)
2139 REJECT("Authoritative directory servers must set ContactInfo");
2140 if (options
->V1AuthoritativeDir
&& !options
->RecommendedVersions
)
2141 REJECT("V1 auth dir servers must set RecommendedVersions.");
2142 if (!options
->RecommendedClientVersions
)
2143 options
->RecommendedClientVersions
=
2144 config_lines_dup(options
->RecommendedVersions
);
2145 if (!options
->RecommendedServerVersions
)
2146 options
->RecommendedServerVersions
=
2147 config_lines_dup(options
->RecommendedVersions
);
2148 if (options
->VersioningAuthoritativeDir
&&
2149 (!options
->RecommendedClientVersions
||
2150 !options
->RecommendedServerVersions
))
2151 REJECT("Versioning auth dir servers must set Recommended*Versions.");
2152 if (options
->UseEntryGuards
) {
2153 log_info(LD_CONFIG
, "Authoritative directory servers can't set "
2154 "UseEntryGuards. Disabling.");
2155 options
->UseEntryGuards
= 0;
2159 if (options
->AuthoritativeDir
&& !options
->DirPort
)
2160 REJECT("Running as authoritative directory, but no DirPort set.");
2162 if (options
->AuthoritativeDir
&& !options
->ORPort
)
2163 REJECT("Running as authoritative directory, but no ORPort set.");
2165 if (options
->AuthoritativeDir
&& options
->ClientOnly
)
2166 REJECT("Running as authoritative directory, but ClientOnly also set.");
2168 if (options
->ConnLimit
<= 0) {
2169 r
= tor_snprintf(buf
, sizeof(buf
),
2170 "ConnLimit must be greater than 0, but was set to %d",
2171 options
->ConnLimit
);
2172 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
2176 if (options
->_AccountingMaxKB
) {
2177 log(LOG_WARN
, LD_CONFIG
, "AccountingMaxKB is deprecated. "
2178 "Say 'AccountingMax %d KB' instead.", options
->_AccountingMaxKB
);
2179 options
->AccountingMax
= U64_LITERAL(1024)*options
->_AccountingMaxKB
;
2180 options
->_AccountingMaxKB
= 0;
2183 if (validate_ports_csv(options
->FirewallPorts
, "FirewallPorts", msg
) < 0)
2186 if (validate_ports_csv(options
->LongLivedPorts
, "LongLivedPorts", msg
) < 0)
2189 if (options
->FascistFirewall
&& !options
->ReachableAddresses
) {
2190 if (smartlist_len(options
->FirewallPorts
)) {
2191 /* We already have firewall ports set, so migrate them to
2192 * ReachableAddresses, which will set ReachableORAddresses and
2193 * ReachableDirAddresses if they aren't set explicitly. */
2194 smartlist_t
*instead
= smartlist_create();
2195 config_line_t
*new_line
= tor_malloc_zero(sizeof(config_line_t
));
2196 new_line
->key
= tor_strdup("ReachableAddresses");
2197 /* If we're configured with the old format, we need to prepend some
2199 SMARTLIST_FOREACH(options
->FirewallPorts
, const char *, portno
,
2201 int p
= atoi(portno
);
2205 tor_snprintf(s
, 16, "*:%d", p
);
2206 smartlist_add(instead
, s
);
2208 new_line
->value
= smartlist_join_strings(instead
,",",0,NULL
);
2209 /* These have been deprecated since 0.1.1.5-alpha-cvs */
2210 log(LOG_NOTICE
, LD_CONFIG
,
2211 "Converting FascistFirewall and FirewallPorts "
2212 "config options to new format: \"ReachableAddresses %s\"",
2214 options
->ReachableAddresses
= new_line
;
2215 SMARTLIST_FOREACH(instead
, char *, cp
, tor_free(cp
));
2216 smartlist_free(instead
);
2218 /* We do not have FirewallPorts set, so add 80 to
2219 * ReachableDirAddresses, and 443 to ReachableORAddresses. */
2220 if (!options
->ReachableDirAddresses
) {
2221 config_line_t
*new_line
= tor_malloc_zero(sizeof(config_line_t
));
2222 new_line
->key
= tor_strdup("ReachableDirAddresses");
2223 new_line
->value
= tor_strdup("*:80");
2224 options
->ReachableDirAddresses
= new_line
;
2225 log(LOG_NOTICE
, LD_CONFIG
, "Converting FascistFirewall config option "
2226 "to new format: \"ReachableDirAddresses *:80\"");
2228 if (!options
->ReachableORAddresses
) {
2229 config_line_t
*new_line
= tor_malloc_zero(sizeof(config_line_t
));
2230 new_line
->key
= tor_strdup("ReachableORAddresses");
2231 new_line
->value
= tor_strdup("*:443");
2232 options
->ReachableORAddresses
= new_line
;
2233 log(LOG_NOTICE
, LD_CONFIG
, "Converting FascistFirewall config option "
2234 "to new format: \"ReachableORAddresses *:443\"");
2239 for (i
=0; i
<3; i
++) {
2240 config_line_t
**linep
=
2241 (i
==0) ? &options
->ReachableAddresses
:
2242 (i
==1) ? &options
->ReachableORAddresses
:
2243 &options
->ReachableDirAddresses
;
2246 /* We need to end with a reject *:*, not an implicit accept *:* */
2248 if (!strcmp((*linep
)->value
, "reject *:*")) /* already there */
2250 linep
= &((*linep
)->next
);
2252 *linep
= tor_malloc_zero(sizeof(config_line_t
));
2253 (*linep
)->key
= tor_strdup(
2254 (i
==0) ? "ReachableAddresses" :
2255 (i
==1) ? "ReachableORAddresses" :
2256 "ReachableDirAddresses");
2257 (*linep
)->value
= tor_strdup("reject *:*");
2263 if ((options
->ReachableAddresses
||
2264 options
->ReachableORAddresses
||
2265 options
->ReachableDirAddresses
) &&
2266 server_mode(options
))
2267 REJECT("Servers must be able to freely connect to the rest "
2268 "of the Internet, so they must not set Reachable*Addresses "
2269 "or FascistFirewall.");
2271 options
->_AllowInvalid
= 0;
2272 if (options
->AllowInvalidNodes
) {
2273 SMARTLIST_FOREACH(options
->AllowInvalidNodes
, const char *, cp
, {
2274 if (!strcasecmp(cp
, "entry"))
2275 options
->_AllowInvalid
|= ALLOW_INVALID_ENTRY
;
2276 else if (!strcasecmp(cp
, "exit"))
2277 options
->_AllowInvalid
|= ALLOW_INVALID_EXIT
;
2278 else if (!strcasecmp(cp
, "middle"))
2279 options
->_AllowInvalid
|= ALLOW_INVALID_MIDDLE
;
2280 else if (!strcasecmp(cp
, "introduction"))
2281 options
->_AllowInvalid
|= ALLOW_INVALID_INTRODUCTION
;
2282 else if (!strcasecmp(cp
, "rendezvous"))
2283 options
->_AllowInvalid
|= ALLOW_INVALID_RENDEZVOUS
;
2285 r
= tor_snprintf(buf
, sizeof(buf
),
2286 "Unrecognized value '%s' in AllowInvalidNodes", cp
);
2287 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
2293 if (options
->SocksPort
>= 1 &&
2294 (options
->PathlenCoinWeight
< 0.0 || options
->PathlenCoinWeight
>= 1.0))
2295 REJECT("PathlenCoinWeight option must be >=0.0 and <1.0.");
2297 if (options
->DirFetchPeriod
&&
2298 options
->DirFetchPeriod
< MIN_DIR_FETCH_PERIOD
) {
2299 log(LOG_WARN
, LD_CONFIG
,
2300 "DirFetchPeriod option must be at least %d seconds. Clipping.",
2301 MIN_DIR_FETCH_PERIOD
);
2302 options
->DirFetchPeriod
= MIN_DIR_FETCH_PERIOD
;
2304 if (options
->StatusFetchPeriod
&&
2305 options
->StatusFetchPeriod
< MIN_STATUS_FETCH_PERIOD
) {
2306 log(LOG_WARN
, LD_CONFIG
,
2307 "StatusFetchPeriod option must be at least %d seconds. Clipping.",
2308 MIN_STATUS_FETCH_PERIOD
);
2309 options
->StatusFetchPeriod
= MIN_STATUS_FETCH_PERIOD
;
2311 if (options
->RendPostPeriod
< MIN_REND_POST_PERIOD
) {
2312 log(LOG_WARN
,LD_CONFIG
,"RendPostPeriod option must be at least %d seconds."
2313 " Clipping.", MIN_REND_POST_PERIOD
);
2314 options
->RendPostPeriod
= MIN_REND_POST_PERIOD
;
2317 if (options
->DirPort
&& ! options
->AuthoritativeDir
) {
2318 if (options
->DirFetchPeriod
> MAX_CACHE_DIR_FETCH_PERIOD
) {
2319 log(LOG_WARN
, LD_CONFIG
, "Caching directory servers must have "
2320 "DirFetchPeriod less than %d seconds. Clipping.",
2321 MAX_CACHE_DIR_FETCH_PERIOD
);
2322 options
->DirFetchPeriod
= MAX_CACHE_DIR_FETCH_PERIOD
;
2324 if (options
->StatusFetchPeriod
> MAX_CACHE_STATUS_FETCH_PERIOD
) {
2325 log(LOG_WARN
, LD_CONFIG
, "Caching directory servers must have "
2326 "StatusFetchPeriod less than %d seconds. Clipping.",
2327 MAX_CACHE_STATUS_FETCH_PERIOD
);
2328 options
->StatusFetchPeriod
= MAX_CACHE_STATUS_FETCH_PERIOD
;
2332 if (options
->DirFetchPeriod
> MAX_DIR_PERIOD
) {
2333 log(LOG_WARN
, LD_CONFIG
, "DirFetchPeriod is too large; clipping to %ds.",
2335 options
->DirFetchPeriod
= MAX_DIR_PERIOD
;
2337 if (options
->StatusFetchPeriod
> MAX_DIR_PERIOD
) {
2338 log(LOG_WARN
, LD_CONFIG
,"StatusFetchPeriod is too large; clipping to %ds.",
2340 options
->StatusFetchPeriod
= MAX_DIR_PERIOD
;
2342 if (options
->RendPostPeriod
> MAX_DIR_PERIOD
) {
2343 log(LOG_WARN
, LD_CONFIG
, "RendPostPeriod is too large; clipping to %ds.",
2345 options
->RendPostPeriod
= MAX_DIR_PERIOD
;
2348 if (options
->KeepalivePeriod
< 1)
2349 REJECT("KeepalivePeriod option must be positive.");
2351 if (options
->BandwidthRate
> INT_MAX
) {
2352 r
= tor_snprintf(buf
, sizeof(buf
),
2353 "BandwidthRate must be less than %d",INT_MAX
);
2354 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
2357 if (options
->BandwidthBurst
> INT_MAX
) {
2358 r
= tor_snprintf(buf
, sizeof(buf
),
2359 "BandwidthBurst must be less than %d",INT_MAX
);
2360 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
2363 if (server_mode(options
) &&
2364 options
->BandwidthRate
< ROUTER_REQUIRED_MIN_BANDWIDTH
*2) {
2365 r
= tor_snprintf(buf
, sizeof(buf
),
2366 "BandwidthRate is set to %d bytes/second. "
2367 "For servers, it must be at least %d.",
2368 (int)options
->BandwidthRate
,
2369 ROUTER_REQUIRED_MIN_BANDWIDTH
*2);
2370 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
2373 if (options
->BandwidthRate
> options
->BandwidthBurst
)
2374 REJECT("BandwidthBurst must be at least equal to BandwidthRate.");
2376 if (accounting_parse_options(options
, 1)<0)
2377 REJECT("Failed to parse accounting options. See logs for details.");
2379 if (options
->HttpProxy
) { /* parse it now */
2380 if (parse_addr_port(options
->HttpProxy
, NULL
,
2381 &options
->HttpProxyAddr
, &options
->HttpProxyPort
) < 0)
2382 REJECT("HttpProxy failed to parse or resolve. Please fix.");
2383 if (options
->HttpProxyPort
== 0) { /* give it a default */
2384 options
->HttpProxyPort
= 80;
2388 if (options
->HttpProxyAuthenticator
) {
2389 if (strlen(options
->HttpProxyAuthenticator
) >= 48)
2390 REJECT("HttpProxyAuthenticator is too long (>= 48 chars).");
2393 if (options
->HttpsProxy
) { /* parse it now */
2394 if (parse_addr_port(options
->HttpsProxy
, NULL
,
2395 &options
->HttpsProxyAddr
, &options
->HttpsProxyPort
) <0)
2396 REJECT("HttpsProxy failed to parse or resolve. Please fix.");
2397 if (options
->HttpsProxyPort
== 0) { /* give it a default */
2398 options
->HttpsProxyPort
= 443;
2402 if (options
->HttpsProxyAuthenticator
) {
2403 if (strlen(options
->HttpsProxyAuthenticator
) >= 48)
2404 REJECT("HttpsProxyAuthenticator is too long (>= 48 chars).");
2407 if (options
->HashedControlPassword
) {
2408 if (decode_hashed_password(NULL
, options
->HashedControlPassword
)<0)
2409 REJECT("Bad HashedControlPassword: wrong length or bad encoding");
2411 if (options
->HashedControlPassword
&& options
->CookieAuthentication
)
2412 REJECT("Cannot set both HashedControlPassword and CookieAuthentication");
2414 if (options
->UseEntryGuards
&& ! options
->NumEntryGuards
)
2415 REJECT("Cannot enable UseEntryGuards with NumEntryGuards set to 0");
2417 if (check_nickname_list(options
->ExitNodes
, "ExitNodes", msg
))
2419 if (check_nickname_list(options
->EntryNodes
, "EntryNodes", msg
))
2421 if (check_nickname_list(options
->ExcludeNodes
, "ExcludeNodes", msg
))
2423 if (check_nickname_list(options
->RendNodes
, "RendNodes", msg
))
2425 if (check_nickname_list(options
->RendNodes
, "RendExcludeNodes", msg
))
2427 if (check_nickname_list(options
->MyFamily
, "MyFamily", msg
))
2429 for (cl
= options
->NodeFamilies
; cl
; cl
= cl
->next
) {
2430 if (check_nickname_list(cl
->value
, "NodeFamily", msg
))
2434 if (validate_addr_policies(options
, msg
) < 0)
2437 for (cl
= options
->RedirectExit
; cl
; cl
= cl
->next
) {
2438 if (parse_redirect_line(NULL
, cl
, msg
)<0)
2442 if (options
->DirServers
) {
2444 !config_lines_eq(options
->DirServers
, old_options
->DirServers
))
2445 COMPLAIN("You have used DirServer to specify directory authorities in "
2446 "your configuration. This is potentially dangerous: it can "
2447 "make you look different from all other Tor users, and hurt "
2448 "your anonymity. Even if you've specified the same "
2449 "authorities as Tor uses by default, the defaults could "
2450 "change in the future. Be sure you know what you're doing.");
2451 for (cl
= options
->DirServers
; cl
; cl
= cl
->next
) {
2452 if (parse_dir_server_line(cl
->value
, 1)<0)
2453 REJECT("DirServer line did not parse. See logs for details.");
2457 if (rend_config_services(options
, 1) < 0)
2458 REJECT("Failed to configure rendezvous options. See logs for details.");
2460 if (parse_virtual_addr_network(options
->VirtualAddrNetwork
, 1, NULL
)<0)
2468 /** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
2471 opt_streq(const char *s1
, const char *s2
)
2475 else if (s1
&& s2
&& !strcmp(s1
,s2
))
2481 /** Check if any of the previous options have changed but aren't allowed to. */
2483 options_transition_allowed(or_options_t
*old
, or_options_t
*new_val
,
2489 if (!opt_streq(old
->PidFile
, new_val
->PidFile
)) {
2490 *msg
= tor_strdup("PidFile is not allowed to change.");
2494 if (old
->RunAsDaemon
!= new_val
->RunAsDaemon
) {
2495 *msg
= tor_strdup("While Tor is running, changing RunAsDaemon "
2500 if (strcmp(old
->DataDirectory
,new_val
->DataDirectory
)!=0) {
2502 int r
= tor_snprintf(buf
, sizeof(buf
),
2503 "While Tor is running, changing DataDirectory "
2504 "(\"%s\"->\"%s\") is not allowed.",
2505 old
->DataDirectory
, new_val
->DataDirectory
);
2506 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
2510 if (!opt_streq(old
->User
, new_val
->User
)) {
2511 *msg
= tor_strdup("While Tor is running, changing User is not allowed.");
2515 if (!opt_streq(old
->Group
, new_val
->Group
)) {
2516 *msg
= tor_strdup("While Tor is running, changing Group is not allowed.");
2520 if (old
->HardwareAccel
!= new_val
->HardwareAccel
) {
2521 *msg
= tor_strdup("While Tor is running, changing HardwareAccel is "
2529 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
2530 * will require us to rotate the cpu and dns workers; else return 0. */
2532 options_transition_affects_workers(or_options_t
*old_options
,
2533 or_options_t
*new_options
)
2535 if (!opt_streq(old_options
->DataDirectory
, new_options
->DataDirectory
) ||
2536 old_options
->NumCpus
!= new_options
->NumCpus
||
2537 old_options
->ORPort
!= new_options
->ORPort
||
2538 old_options
->SafeLogging
!= new_options
->SafeLogging
||
2539 !config_lines_eq(old_options
->Logs
, new_options
->Logs
))
2542 /* Check whether log options match. */
2544 /* Nothing that changed matters. */
2548 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
2549 * will require us to generate a new descriptor; else return 0. */
2551 options_transition_affects_descriptor(or_options_t
*old_options
,
2552 or_options_t
*new_options
)
2554 if (!opt_streq(old_options
->DataDirectory
, new_options
->DataDirectory
) ||
2555 !opt_streq(old_options
->Nickname
,new_options
->Nickname
) ||
2556 !opt_streq(old_options
->Address
,new_options
->Address
) ||
2557 !config_lines_eq(old_options
->ExitPolicy
,new_options
->ExitPolicy
) ||
2558 old_options
->ORPort
!= new_options
->ORPort
||
2559 old_options
->DirPort
!= new_options
->DirPort
||
2560 old_options
->ClientOnly
!= new_options
->ClientOnly
||
2561 old_options
->NoPublish
!= new_options
->NoPublish
||
2562 old_options
->PublishServerDescriptor
!=
2563 new_options
->PublishServerDescriptor
||
2564 old_options
->BandwidthRate
!= new_options
->BandwidthRate
||
2565 old_options
->BandwidthBurst
!= new_options
->BandwidthBurst
||
2566 !opt_streq(old_options
->ContactInfo
, new_options
->ContactInfo
) ||
2567 !opt_streq(old_options
->MyFamily
, new_options
->MyFamily
) ||
2568 !opt_streq(old_options
->AccountingStart
, new_options
->AccountingStart
) ||
2569 old_options
->AccountingMax
!= new_options
->AccountingMax
)
2576 /** Return the directory on windows where we expect to find our application
2579 get_windows_conf_root(void)
2581 static int is_set
= 0;
2582 static char path
[MAX_PATH
+1];
2591 /* Find X:\documents and settings\username\application data\ .
2592 * We would use SHGetSpecialFolder path, but that wasn't added until IE4.
2594 if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL
, CSIDL_APPDATA
,
2596 GetCurrentDirectory(MAX_PATH
, path
);
2599 "I couldn't find your application data folder: are you "
2600 "running an ancient version of Windows 95? Defaulting to \"%s\"",
2604 /* Convert the path from an "ID List" (whatever that is!) to a path. */
2605 result
= SHGetPathFromIDList(idl
, path
);
2606 /* Now we need to free the */
2609 m
->lpVtbl
->Free(m
, idl
);
2610 m
->lpVtbl
->Release(m
);
2612 if (!SUCCEEDED(result
)) {
2615 strlcat(path
,"\\tor",MAX_PATH
);
2621 /** Return the default location for our torrc file. */
2623 get_default_conf_file(void)
2626 static char path
[MAX_PATH
+1];
2627 strlcpy(path
, get_windows_conf_root(), MAX_PATH
);
2628 strlcat(path
,"\\torrc",MAX_PATH
);
2631 return (CONFDIR
"/torrc");
2635 /** Verify whether lst is a string containing valid-looking space-separated
2636 * nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
2639 check_nickname_list(const char *lst
, const char *name
, char **msg
)
2646 sl
= smartlist_create();
2647 smartlist_split_string(sl
, lst
, ",", SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 0);
2648 SMARTLIST_FOREACH(sl
, const char *, s
,
2650 if (!is_legal_nickname_or_hexdigest(s
)) {
2652 int tmp
= tor_snprintf(buf
, sizeof(buf
),
2653 "Invalid nickname '%s' in %s line", s
, name
);
2654 *msg
= tor_strdup(tmp
>= 0 ? buf
: "internal error");
2659 SMARTLIST_FOREACH(sl
, char *, s
, tor_free(s
));
2664 /** Read a configuration file into <b>options</b>, finding the configuration
2665 * file location based on the command line. After loading the options,
2666 * validate them for consistency, then take actions based on them.
2667 * Return 0 if success, -1 if failure. */
2669 options_init_from_torrc(int argc
, char **argv
)
2671 or_options_t
*oldoptions
, *newoptions
;
2673 char *cf
=NULL
, *fname
=NULL
, *errmsg
=NULL
;
2675 int using_default_torrc
;
2676 static char **backup_argv
;
2677 static int backup_argc
;
2679 if (argv
) { /* first time we're called. save commandline args */
2683 } else { /* we're reloading. need to clean up old options first. */
2686 oldoptions
= get_options();
2688 if (argc
> 1 && (!strcmp(argv
[1], "-h") || !strcmp(argv
[1],"--help"))) {
2693 if (argc
> 1 && (!strcmp(argv
[1],"--version"))) {
2694 printf("Tor version %s.\n",VERSION
);
2695 if (argc
> 2 && (!strcmp(argv
[2],"--version"))) {
2696 print_cvs_version();
2701 newoptions
= tor_malloc_zero(sizeof(or_options_t
));
2702 newoptions
->_magic
= OR_OPTIONS_MAGIC
;
2703 options_init(newoptions
);
2705 /* learn config file name */
2707 using_default_torrc
= 1;
2708 newoptions
->command
= CMD_RUN_TOR
;
2709 for (i
= 1; i
< argc
; ++i
) {
2710 if (i
< argc
-1 && !strcmp(argv
[i
],"-f")) {
2712 log(LOG_WARN
, LD_CONFIG
, "Duplicate -f options on command line.");
2715 fname
= tor_strdup(argv
[i
+1]);
2716 using_default_torrc
= 0;
2718 } else if (!strcmp(argv
[i
],"--list-fingerprint")) {
2719 newoptions
->command
= CMD_LIST_FINGERPRINT
;
2720 } else if (!strcmp(argv
[i
],"--hash-password")) {
2721 newoptions
->command
= CMD_HASH_PASSWORD
;
2722 newoptions
->command_arg
= tor_strdup( (i
< argc
-1) ? argv
[i
+1] : "");
2724 } else if (!strcmp(argv
[i
],"--verify-config")) {
2725 newoptions
->command
= CMD_VERIFY_CONFIG
;
2728 if (using_default_torrc
) {
2729 /* didn't find one, try CONFDIR */
2730 const char *dflt
= get_default_conf_file();
2732 if (dflt
&& file_status(dflt
) == FN_FILE
) {
2733 fname
= tor_strdup(dflt
);
2736 fn
= expand_filename("~/.torrc");
2737 if (fn
&& file_status(fn
) == FN_FILE
) {
2741 fname
= tor_strdup(dflt
);
2744 fname
= tor_strdup(dflt
);
2749 log(LOG_DEBUG
, LD_CONFIG
, "Opening config file \"%s\"", fname
);
2751 tor_free(torrc_fname
);
2752 torrc_fname
= fname
;
2754 /* get config lines, assign them */
2755 if (file_status(fname
) != FN_FILE
||
2756 !(cf
= read_file_to_str(fname
,0))) {
2757 if (using_default_torrc
== 1) {
2758 log(LOG_NOTICE
, LD_CONFIG
, "Configuration file \"%s\" not present, "
2759 "using reasonable defaults.", fname
);
2760 tor_free(fname
); /* sets fname to NULL */
2763 log(LOG_WARN
, LD_CONFIG
,
2764 "Unable to open configuration file \"%s\".", fname
);
2767 } else { /* it opened successfully. use it. */
2768 retval
= config_get_lines(cf
, &cl
);
2772 retval
= config_assign(&options_format
, newoptions
, cl
, 0, 0, &errmsg
);
2773 config_free_lines(cl
);
2778 /* Go through command-line variables too */
2779 if (config_get_commandlines(argc
, argv
, &cl
) < 0)
2781 retval
= config_assign(&options_format
, newoptions
, cl
, 0, 0, &errmsg
);
2782 config_free_lines(cl
);
2786 /* Validate newoptions */
2787 if (options_validate(oldoptions
, newoptions
, 0, &errmsg
) < 0)
2790 if (options_transition_allowed(oldoptions
, newoptions
, &errmsg
) < 0)
2793 if (set_options(newoptions
, &errmsg
))
2794 goto err
; /* frees and replaces old options */
2800 config_free(&options_format
, newoptions
);
2802 log(LOG_WARN
,LD_CONFIG
,"Failed to parse/validate config: %s", errmsg
);
2808 /** Return the location for our configuration file.
2811 get_torrc_fname(void)
2816 return get_default_conf_file();
2819 /** Adjust the address map mased on the MapAddress elements in the
2820 * configuration <b>options</b>
2823 config_register_addressmaps(or_options_t
*options
)
2829 addressmap_clear_configured();
2830 elts
= smartlist_create();
2831 for (opt
= options
->AddressMap
; opt
; opt
= opt
->next
) {
2832 smartlist_split_string(elts
, opt
->value
, NULL
,
2833 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 2);
2834 if (smartlist_len(elts
) >= 2) {
2835 from
= smartlist_get(elts
,0);
2836 to
= smartlist_get(elts
,1);
2837 if (!is_plausible_address(from
)) {
2839 "Skipping invalid argument '%s' to MapAddress", from
);
2840 } else if (!is_plausible_address(to
)) {
2842 "Skipping invalid argument '%s' to MapAddress", to
);
2844 addressmap_register(from
, tor_strdup(to
), 0);
2845 if (smartlist_len(elts
)>2) {
2846 log_warn(LD_CONFIG
,"Ignoring extra arguments to MapAddress.");
2850 log_warn(LD_CONFIG
,"MapAddress '%s' has too few arguments. Ignoring.",
2853 SMARTLIST_FOREACH(elts
, char*, cp
, tor_free(cp
));
2854 smartlist_clear(elts
);
2856 smartlist_free(elts
);
2859 /** If <b>range</b> is of the form MIN-MAX, for MIN and MAX both
2860 * recognized log severity levels, set *<b>min_out</b> to MIN and
2861 * *<b>max_out</b> to MAX and return 0. Else, if <b>range</b> is of
2862 * the form MIN, act as if MIN-err had been specified. Else, warn and
2866 parse_log_severity_range(const char *range
, int *min_out
, int *max_out
)
2868 int levelMin
, levelMax
;
2870 cp
= strchr(range
, '-');
2873 levelMin
= LOG_DEBUG
;
2875 char *tmp_sev
= tor_strndup(range
, cp
- range
);
2876 levelMin
= parse_log_level(tmp_sev
);
2878 log_warn(LD_CONFIG
, "Unrecognized log severity '%s': must be one of "
2879 "err|warn|notice|info|debug", tmp_sev
);
2888 levelMax
= parse_log_level(cp
+1);
2890 log_warn(LD_CONFIG
, "Unrecognized log severity '%s': must be one of "
2891 "err|warn|notice|info|debug", cp
+1);
2896 levelMin
= parse_log_level(range
);
2898 log_warn(LD_CONFIG
, "Unrecognized log severity '%s': must be one of "
2899 "err|warn|notice|info|debug", range
);
2905 *min_out
= levelMin
;
2906 *max_out
= levelMax
;
2911 /** Try to convert a pair of old-style logging options [LogLevel, and
2912 * (LogFile/Syslog)] to a new-style option, and add the new option to
2915 convert_log_option(or_options_t
*options
, config_line_t
*level_opt
,
2916 config_line_t
*file_opt
, int isDaemon
)
2918 int levelMin
= -1, levelMax
= -1;
2921 if (parse_log_severity_range(level_opt
->value
, &levelMin
, &levelMax
))
2924 if (levelMin
< 0 && levelMax
< 0) {
2925 levelMin
= LOG_NOTICE
;
2927 } else if (levelMin
< 0) {
2928 levelMin
= levelMax
;
2933 if (file_opt
&& !strcasecmp(file_opt
->key
, "LogFile")) {
2934 if (add_single_log_option(options
, levelMin
, levelMax
, "file",
2935 file_opt
->value
) < 0) {
2936 log_warn(LD_FS
, "Cannot write to LogFile \"%s\": %s.", file_opt
->value
,
2940 } else if (file_opt
&& !strcasecmp(file_opt
->key
, "SysLog")) {
2941 if (add_single_log_option(options
, levelMin
, levelMax
, "syslog", NULL
) < 0)
2943 } else if (!isDaemon
) {
2944 add_single_log_option(options
, levelMin
, levelMax
, "stdout", NULL
);
2950 * Initialize the logs based on the configuration file.
2953 options_init_logs(or_options_t
*options
, int validate_only
)
2958 int daemon
= options
->RunAsDaemon
;
2961 elts
= smartlist_create();
2963 for (opt
= options
->Logs
; opt
; opt
= opt
->next
) {
2964 int levelMin
=LOG_DEBUG
, levelMax
=LOG_ERR
;
2965 smartlist_split_string(elts
, opt
->value
, NULL
,
2966 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 3);
2967 if (smartlist_len(elts
) == 0) {
2968 log_warn(LD_CONFIG
, "Bad syntax on Log option 'Log %s'", opt
->value
);
2969 ok
= 0; goto cleanup
;
2971 if (parse_log_severity_range(smartlist_get(elts
,0), &levelMin
,
2973 ok
= 0; goto cleanup
;
2975 if (smartlist_len(elts
) < 2) { /* only loglevels were provided */
2976 if (!validate_only
) {
2979 "Can't log to stdout with RunAsDaemon set; skipping stdout");
2981 add_stream_log(levelMin
, levelMax
, "<stdout>", stdout
);
2986 if (!strcasecmp(smartlist_get(elts
,1), "file")) {
2987 if (smartlist_len(elts
) != 3) {
2988 log_warn(LD_CONFIG
, "Bad syntax on Log option 'Log %s'", opt
->value
);
2989 ok
= 0; goto cleanup
;
2991 if (!validate_only
) {
2992 if (add_file_log(levelMin
, levelMax
, smartlist_get(elts
, 2)) < 0) {
2993 log_warn(LD_CONFIG
, "Couldn't open file for 'Log %s'", opt
->value
);
2999 if (smartlist_len(elts
) != 2) {
3000 log_warn(LD_CONFIG
, "Bad syntax on Log option 'Log %s'", opt
->value
);
3001 ok
= 0; goto cleanup
;
3003 if (!strcasecmp(smartlist_get(elts
,1), "stdout")) {
3005 log_warn(LD_CONFIG
, "Can't log to stdout with RunAsDaemon set.");
3006 ok
= 0; goto cleanup
;
3008 if (!validate_only
) {
3009 add_stream_log(levelMin
, levelMax
, "<stdout>", stdout
);
3011 } else if (!strcasecmp(smartlist_get(elts
,1), "stderr")) {
3013 log_warn(LD_CONFIG
, "Can't log to stderr with RunAsDaemon set.");
3014 ok
= 0; goto cleanup
;
3016 if (!validate_only
) {
3017 add_stream_log(levelMin
, levelMax
, "<stderr>", stderr
);
3019 } else if (!strcasecmp(smartlist_get(elts
,1), "syslog")) {
3020 #ifdef HAVE_SYSLOG_H
3022 add_syslog_log(levelMin
, levelMax
);
3024 log_warn(LD_CONFIG
, "Syslog is not supported in this compilation.");
3027 log_warn(LD_CONFIG
, "Unrecognized log type %s",
3028 (const char*)smartlist_get(elts
,1));
3029 if (strchr(smartlist_get(elts
,1), '/') ||
3030 strchr(smartlist_get(elts
,1), '\\')) {
3031 log_warn(LD_CONFIG
, "Did you mean to say 'Log file %s' ?",
3032 (const char *)smartlist_get(elts
,1));
3034 ok
= 0; goto cleanup
;
3037 SMARTLIST_FOREACH(elts
, char*, cp
, tor_free(cp
));
3038 smartlist_clear(elts
);
3040 smartlist_free(elts
);
3045 /** Add a single option of the form Log min-max \<type\> [fname] to options. */
3047 add_single_log_option(or_options_t
*options
, int minSeverity
, int maxSeverity
,
3048 const char *type
, const char *fname
)
3053 len
= 256 + fname
?strlen(fname
):0;
3054 buf
= tor_malloc(len
);
3056 if (tor_snprintf(buf
, len
, "%s%s%s %s%s%s",
3057 log_level_to_string(minSeverity
),
3058 maxSeverity
== LOG_ERR
? "" : "-",
3059 maxSeverity
== LOG_ERR
? "" : log_level_to_string(maxSeverity
),
3060 type
, fname
?" ":"", fname
?fname
:"")<0) {
3061 log_warn(LD_BUG
, "Normalized log option too long.");
3066 log(LOG_WARN
, LD_CONFIG
, "The old LogLevel/LogFile/DebugLogFile/SysLog "
3067 "options are deprecated, and will go away soon. Your new torrc line "
3068 "should be: 'Log %s'", buf
);
3069 config_line_append(&options
->Logs
, "Log", buf
);
3074 /** Convert all old-style logging options to new-style Log options. Return 0
3075 * on success, -1 on failure. */
3077 normalize_log_options(or_options_t
*options
)
3079 /* The order of options is: Level? (File Level?)+
3081 config_line_t
*opt
= options
->OldLogOptions
;
3083 /* Special case for if first option is LogLevel. */
3084 if (opt
&& !strcasecmp(opt
->key
, "LogLevel")) {
3085 if (opt
->next
&& (!strcasecmp(opt
->next
->key
, "LogFile") ||
3086 !strcasecmp(opt
->next
->key
, "SysLog"))) {
3087 if (convert_log_option(options
, opt
, opt
->next
, options
->RunAsDaemon
)< 0)
3089 opt
= opt
->next
->next
;
3090 } else if (!opt
->next
) {
3091 if (convert_log_option(options
, opt
, NULL
, options
->RunAsDaemon
) < 0)
3095 ; /* give warning below */
3100 if (!strcasecmp(opt
->key
, "LogLevel")) {
3101 log_warn(LD_CONFIG
, "Two LogLevel options in a row without "
3102 "intervening LogFile or SysLog");
3105 tor_assert(!strcasecmp(opt
->key
, "LogFile") ||
3106 !strcasecmp(opt
->key
, "SysLog"));
3107 if (opt
->next
&& !strcasecmp(opt
->next
->key
, "LogLevel")) {
3108 /* LogFile/SysLog followed by LogLevel */
3109 if (convert_log_option(options
,opt
->next
,opt
, options
->RunAsDaemon
) <0)
3111 opt
= opt
->next
->next
;
3113 /* LogFile/SysLog followed by LogFile/SysLog or end of list. */
3114 if (convert_log_option(options
,NULL
, opt
, options
->RunAsDaemon
) < 0)
3121 if (options
->DebugLogFile
) {
3122 if (add_single_log_option(options
, LOG_DEBUG
, LOG_ERR
, "file",
3123 options
->DebugLogFile
) < 0)
3127 tor_free(options
->DebugLogFile
);
3128 config_free_lines(options
->OldLogOptions
);
3129 options
->OldLogOptions
= NULL
;
3134 /** Parse a single RedirectExit line's contents from <b>line</b>. If
3135 * they are valid, and <b>result</b> is not NULL, add an element to
3136 * <b>result</b> and return 0. Else if they are valid, return 0.
3137 * Else set *msg and return -1. */
3139 parse_redirect_line(smartlist_t
*result
, config_line_t
*line
, char **msg
)
3141 smartlist_t
*elements
= NULL
;
3146 r
= tor_malloc_zero(sizeof(exit_redirect_t
));
3147 elements
= smartlist_create();
3148 smartlist_split_string(elements
, line
->value
, NULL
,
3149 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 0);
3150 if (smartlist_len(elements
) != 2) {
3151 *msg
= tor_strdup("Wrong number of elements in RedirectExit line");
3154 if (parse_addr_and_port_range(smartlist_get(elements
,0),&r
->addr
,&r
->mask
,
3155 &r
->port_min
,&r
->port_max
)) {
3156 *msg
= tor_strdup("Error parsing source address in RedirectExit line");
3159 if (0==strcasecmp(smartlist_get(elements
,1), "pass")) {
3162 if (parse_addr_port(smartlist_get(elements
,1),NULL
,&r
->addr_dest
,
3164 *msg
= tor_strdup("Error parsing dest address in RedirectExit line");
3174 SMARTLIST_FOREACH(elements
, char *, cp
, tor_free(cp
));
3175 smartlist_free(elements
);
3178 smartlist_add(result
, r
);
3188 /** Read the contents of a DirServer line from <b>line</b>. Return 0
3189 * if the line is well-formed, and -1 if it isn't. If
3190 * <b>validate_only</b> is 0, and the line is well-formed, then add
3191 * the dirserver described in the line as a valid server. */
3193 parse_dir_server_line(const char *line
, int validate_only
)
3195 smartlist_t
*items
= NULL
;
3197 char *addrport
=NULL
, *address
=NULL
, *nickname
=NULL
, *fingerprint
=NULL
;
3199 char digest
[DIGEST_LEN
];
3200 int is_v1_authority
= 0;
3202 items
= smartlist_create();
3203 smartlist_split_string(items
, line
, NULL
,
3204 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, -1);
3205 if (smartlist_len(items
) < 2) {
3206 log_warn(LD_CONFIG
, "Too few arguments to DirServer line.");
3211 if (is_legal_nickname(smartlist_get(items
, 0))) {
3212 nickname
= smartlist_get(items
, 0);
3213 smartlist_del_keeporder(items
, 0);
3216 if (!strcmp(smartlist_get(items
, 0), "v1")) {
3217 char *v1
= smartlist_get(items
, 0);
3219 is_v1_authority
= 1;
3220 smartlist_del_keeporder(items
, 0);
3223 if (smartlist_len(items
) < 2) {
3224 log_warn(LD_CONFIG
, "Too few arguments to DirServer line.");
3227 addrport
= smartlist_get(items
, 0);
3228 if (parse_addr_port(addrport
, &address
, NULL
, &port
)<0) {
3229 log_warn(LD_CONFIG
, "Error parsing DirServer address '%s'", addrport
);
3233 log_warn(LD_CONFIG
, "Missing port in DirServer address '%s'",addrport
);
3236 smartlist_del_keeporder(items
, 0);
3238 fingerprint
= smartlist_join_strings(items
, "", 0, NULL
);
3239 if (strlen(fingerprint
) != HEX_DIGEST_LEN
) {
3240 log_warn(LD_CONFIG
, "Key digest for DirServer is wrong length.");
3243 if (base16_decode(digest
, DIGEST_LEN
, fingerprint
, HEX_DIGEST_LEN
)<0) {
3244 log_warn(LD_CONFIG
, "Unable to decode DirServer key digest.");
3248 if (!validate_only
) {
3249 log_debug(LD_DIR
, "Trusted dirserver at %s:%d (%s)", address
, (int)port
,
3250 (char*)smartlist_get(items
,1));
3251 add_trusted_dir_server(nickname
, address
, port
, digest
, is_v1_authority
);
3261 SMARTLIST_FOREACH(items
, char*, s
, tor_free(s
));
3262 smartlist_free(items
);
3266 tor_free(fingerprint
);
3270 /** Adjust the value of options->DataDirectory, or fill it in if it's
3271 * absent. Return 0 on success, -1 on failure. */
3273 normalize_data_directory(or_options_t
*options
)
3277 if (options
->DataDirectory
)
3278 return 0; /* all set */
3279 p
= tor_malloc(MAX_PATH
);
3280 strlcpy(p
,get_windows_conf_root(),MAX_PATH
);
3281 options
->DataDirectory
= p
;
3284 const char *d
= options
->DataDirectory
;
3288 if (strncmp(d
,"~/",2) == 0) {
3289 char *fn
= expand_filename(d
);
3291 log_err(LD_CONFIG
,"Failed to expand filename \"%s\".", d
);
3294 if (!options
->DataDirectory
&& !strcmp(fn
,"/.tor")) {
3295 /* If our homedir is /, we probably don't want to use it. */
3296 /* XXXX Default to /var/lib/tor? */
3298 "Default DataDirectory is \"~/.tor\". This expands to "
3299 "\"%s\", which is probably not what you want. Using \"%s/tor\" "
3300 "instead", fn
, LOCALSTATEDIR
);
3302 fn
= tor_strdup(LOCALSTATEDIR
"/tor");
3305 tor_free(options
->DataDirectory
);
3306 options
->DataDirectory
= fn
;
3312 /** Check and normalize the value of options->DataDirectory; return 0 if it
3313 * sane, -1 otherwise. */
3315 validate_data_directory(or_options_t
*options
)
3317 if (normalize_data_directory(options
) < 0)
3319 tor_assert(options
->DataDirectory
);
3320 if (strlen(options
->DataDirectory
) > (512-128)) {
3321 log_err(LD_CONFIG
, "DataDirectory is too long.");
3327 /** This string must remain the same forevermore. It is how we
3328 * recognize that the torrc file doesn't need to be backed up. */
3329 #define GENERATED_FILE_PREFIX "# This file was generated by Tor; " \
3330 "if you edit it, comments will not be preserved"
3331 /** This string can change; it tries to give the reader an idea
3332 * that editing this file by hand is not a good plan. */
3333 #define GENERATED_FILE_COMMENT "# If you want a config file with " \
3334 "comments, look for torrc.orig.1 or similar"
3336 /** Save a configuration file for the configuration in <b>options</b>
3337 * into the file <b>fname</b>. If the file already exists, and
3338 * doesn't begin with GENERATED_FILE_PREFIX, rename it. Otherwise
3339 * replace it. Return 0 on success, -1 on failure. */
3341 write_configuration_file(const char *fname
, or_options_t
*options
)
3343 char *old_val
=NULL
, *new_val
=NULL
, *new_conf
=NULL
;
3344 int rename_old
= 0, r
;
3348 switch (file_status(fname
)) {
3350 old_val
= read_file_to_str(fname
, 0);
3351 if (strcmpstart(old_val
, GENERATED_FILE_PREFIX
)) {
3360 "Config file \"%s\" is not a file? Failing.", fname
);
3365 if (!(new_conf
= options_dump(options
, 1))) {
3366 log_warn(LD_BUG
, "Couldn't get configuration string");
3370 len
= strlen(new_conf
)+256;
3371 new_val
= tor_malloc(len
);
3372 tor_snprintf(new_val
, len
, "%s\n%s\n\n%s",
3373 GENERATED_FILE_PREFIX
, GENERATED_FILE_COMMENT
, new_conf
);
3377 size_t fn_tmp_len
= strlen(fname
)+32;
3379 tor_assert(fn_tmp_len
> strlen(fname
)); /*check for overflow*/
3380 fn_tmp
= tor_malloc(fn_tmp_len
);
3382 if (tor_snprintf(fn_tmp
, fn_tmp_len
, "%s.orig.%d", fname
, i
)<0) {
3383 log_warn(LD_BUG
, "tor_snprintf failed inexplicably");
3387 if (file_status(fn_tmp
) == FN_NOENT
)
3391 log_notice(LD_CONFIG
, "Renaming old configuration file to \"%s\"", fn_tmp
);
3392 if (rename(fname
, fn_tmp
) < 0) {
3393 log_warn(LD_FS
, "Couldn't rename \"%s\" to \"%s\": %s",
3394 fname
, fn_tmp
, strerror(errno
));
3401 if (write_str_to_file(fname
, new_val
, 0) < 0)
3415 * Save the current configuration file value to disk. Return 0 on
3416 * success, -1 on failure.
3419 options_save_current(void)
3422 /* XXX This fails if we can't write to our configuration file.
3423 * Arguably, we should try falling back to datadirectory or something.
3424 * But just as arguably, we shouldn't. */
3425 return write_configuration_file(torrc_fname
, get_options());
3427 return write_configuration_file(get_default_conf_file(), get_options());
3430 /** Mapping from a unit name to a multiplier for converting that unit into a
3432 struct unit_table_t
{
3434 uint64_t multiplier
;
3437 static struct unit_table_t memory_units
[] = {
3443 { "kilobyte", 1<<10 },
3444 { "kilobytes", 1<<10 },
3447 { "megabyte", 1<<20 },
3448 { "megabytes", 1<<20 },
3450 { "gigabyte", 1<<30 },
3451 { "gigabytes", 1<<30 },
3452 { "tb", U64_LITERAL(1)<<40 },
3453 { "terabyte", U64_LITERAL(1)<<40 },
3454 { "terabytes", U64_LITERAL(1)<<40 },
3458 static struct unit_table_t time_units
[] = {
3466 { "day", 24*60*60 },
3467 { "days", 24*60*60 },
3468 { "week", 7*24*60*60 },
3469 { "weeks", 7*24*60*60 },
3473 /** Parse a string <b>val</b> containing a number, zero or more
3474 * spaces, and an optional unit string. If the unit appears in the
3475 * table <b>u</b>, then multiply the number by the unit multiplier.
3476 * On success, set *<b>ok</b> to 1 and return this product.
3477 * Otherwise, set *<b>ok</b> to 0.
3480 config_parse_units(const char *val
, struct unit_table_t
*u
, int *ok
)
3487 v
= tor_parse_uint64(val
, 10, 0, UINT64_MAX
, ok
, &cp
);
3494 while (TOR_ISSPACE(*cp
))
3496 for ( ;u
->unit
;++u
) {
3497 if (!strcasecmp(u
->unit
, cp
)) {
3503 log_warn(LD_CONFIG
, "Unknown unit '%s'.", cp
);
3508 /** Parse a string in the format "number unit", where unit is a unit of
3509 * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
3510 * and return the number of bytes specified. Otherwise, set
3511 * *<b>ok</b> to false and return 0. */
3513 config_parse_memunit(const char *s
, int *ok
)
3515 return config_parse_units(s
, memory_units
, ok
);
3518 /** Parse a string in the format "number unit", where unit is a unit of time.
3519 * On success, set *<b>ok</b> to true and return the number of seconds in
3520 * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
3523 config_parse_interval(const char *s
, int *ok
)
3526 r
= config_parse_units(s
, time_units
, ok
);
3530 log_warn(LD_CONFIG
, "Interval '%s' is too long", s
);
3538 * Initialize the libevent library.
3543 configure_libevent_logging();
3544 /* If the kernel complains that some method (say, epoll) doesn't
3545 * exist, we don't care about it, since libevent will cope.
3547 suppress_libevent_log_msg("Function not implemented");
3549 setenv("EVENT_NOKQUEUE","1",1);
3552 suppress_libevent_log_msg(NULL
);
3553 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
3554 /* Making this a NOTICE for now so we can link bugs to a libevent versions
3555 * or methods better. */
3556 log(LOG_NOTICE
, LD_GENERAL
,
3557 "Initialized libevent version %s using method %s. Good.",
3558 event_get_version(), event_get_method());
3559 check_libevent_version(event_get_method(), event_get_version(),
3560 get_options()->ORPort
!= 0);
3562 log(LOG_NOTICE
, LD_GENERAL
,
3563 "Initialized old libevent (version 1.0b or earlier).");
3564 log(LOG_WARN
, LD_GENERAL
,
3565 "You have a very old version of libevent. It is likely to be buggy; "
3566 "please consider building Tor with a more recent version.");
3570 #if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
3572 * Compare the given libevent method and version to a list of versions
3573 * which are known not to work. Warn the user as appropriate.
3577 check_libevent_version(const char *m
, const char *v
, int server
)
3579 int buggy
= 0, iffy
= 0, slow
= 0;
3583 if (!strcmp(m
, "kqueue")) {
3584 if (!strcmp(v
, "1.0c") || !strcmp(v
, "1.0d") || !strcmp(v
, "1.0e") ||
3585 !strcmp(v
, "1.1")) {
3588 } else if (!strcmp(m
, "epoll")) {
3589 if (!strcmp(v
, "1.0c") || !strcmp(v
, "1.0d") || !strcmp(v
, "1.0e"))
3591 } else if (!strcmp(m
, "poll")) {
3592 if (!strcmp(v
, "1.0c") || !strcmp(v
, "1.0d"))
3594 else if (!strcmp(v
, "1.0e"))
3596 } else if (!strcmp(m
, "poll")) {
3597 if (!strcmp(v
, "1.0c") || !strcmp(v
, "1.0d") || !strcmp(v
, "1.0e"))
3602 log(LOG_WARN
, LD_GENERAL
,
3603 "There are known bugs in using %s with libevent %s. "
3604 "Please use the latest version of libevent.", m
, v
);
3606 log(LOG_WARN
, LD_GENERAL
,
3607 "There are minor bugs in using %s with libevent %s. "
3608 "You may want to use the latest version of libevent.", m
, v
);
3609 } else if (slow
&& server
) {
3610 log(LOG_WARN
, LD_GENERAL
,
3611 "libevent %s can be very slow with %s. "
3612 "When running a server, please use the latest version of libevent.",
3619 /** Return the persistent state struct for this Tor. */
3623 return global_state
;
3626 /** Return the filename used to write and read the persistent state. */
3628 get_or_state_fname(void)
3631 or_options_t
*options
= get_options();
3632 size_t len
= strlen(options
->DataDirectory
) + 16;
3633 fname
= tor_malloc(len
);
3634 tor_snprintf(fname
, len
, "%s/state", options
->DataDirectory
);
3638 /** Return 0 if every setting in <b>state</b> is reasonable, and a
3639 * permissible transition from <b>old_state</b>. Else warn and return -1.
3640 * Should have no side effects, except for normalizing the contents of
3643 /* XXX from_setconf is here because of bug 238 */
3645 or_state_validate(or_state_t
*old_state
, or_state_t
*state
,
3646 int from_setconf
, char **msg
)
3648 if (entry_guards_parse_state(state
, 0, msg
)<0) {
3651 if (state
->TorVersion
) {
3653 if (tor_version_parse(state
->TorVersion
, &v
)) {
3654 log_warn(LD_GENERAL
, "Can't parse Tor version '%s' from your state "
3655 "file. Proceeding anyway.", state
->TorVersion
);
3656 } else { /* take action based on v */
3657 if (tor_version_as_new_as(state
->TorVersion
, "0.1.1.10-alpha") &&
3658 !tor_version_as_new_as(state
->TorVersion
, "0.1.1.16-rc-cvs")) {
3659 log_notice(LD_CONFIG
, "Detected state file from buggy version '%s'. "
3660 "Enabling workaround to choose working entry guards.",
3662 config_free_lines(state
->EntryGuards
);
3663 state
->EntryGuards
= NULL
;
3670 /** Replace the current persistent state with <b>new_state</b> */
3672 or_state_set(or_state_t
*new_state
)
3675 tor_assert(new_state
);
3677 config_free(&state_format
, global_state
);
3678 global_state
= new_state
;
3679 if (entry_guards_parse_state(global_state
, 1, &err
)<0) {
3680 log_warn(LD_GENERAL
,"%s",err
);
3683 if (rep_hist_load_state(global_state
, &err
)<0) {
3684 log_warn(LD_GENERAL
,"Unparseable bandwidth history state: %s",err
);
3689 /** Reload the persistent state from disk, generating a new state as needed.
3690 * Return 0 on success, less than 0 on failure.
3695 or_state_t
*new_state
= NULL
;
3696 char *contents
= NULL
, *fname
;
3697 char *errmsg
= NULL
;
3700 fname
= get_or_state_fname();
3701 switch (file_status(fname
)) {
3703 if (!(contents
= read_file_to_str(fname
, 0))) {
3704 log_warn(LD_FS
, "Unable to read state file \"%s\"", fname
);
3711 log_warn(LD_GENERAL
,"State file \"%s\" is not a file? Failing.", fname
);
3714 new_state
= tor_malloc_zero(sizeof(or_state_t
));
3715 new_state
->_magic
= OR_STATE_MAGIC
;
3716 config_init(&state_format
, new_state
);
3718 config_line_t
*lines
=NULL
;
3720 if (config_get_lines(contents
, &lines
)<0)
3722 assign_retval
= config_assign(&state_format
, new_state
,
3723 lines
, 0, 0, &errmsg
);
3724 config_free_lines(lines
);
3725 if (assign_retval
<0)
3729 if (or_state_validate(NULL
, new_state
, 1, &errmsg
) < 0) {
3734 log_info(LD_GENERAL
, "Loaded state from \"%s\"", fname
);
3736 log_info(LD_GENERAL
, "Initialized state");
3737 or_state_set(new_state
);
3740 global_state
->dirty
= 1;
3747 log_warn(LD_GENERAL
, "%s", errmsg
);
3753 config_free(&state_format
, new_state
);
3758 /** Write the persistent state to disk. Return 0 for success, <0 on failure. */
3762 char *state
, *contents
;
3763 char tbuf
[ISO_TIME_LEN
+1];
3767 tor_assert(global_state
);
3769 entry_guards_update_state(global_state
);
3770 rep_hist_update_state(global_state
);
3772 if (!global_state
->dirty
)
3775 global_state
->LastWritten
= time(NULL
);
3776 tor_free(global_state
->TorVersion
);
3777 global_state
->TorVersion
= tor_strdup("Tor " VERSION
);
3778 state
= config_dump(&state_format
, global_state
, 0);
3779 len
= strlen(state
)+128;
3780 contents
= tor_malloc(len
);
3781 format_local_iso_time(tbuf
, time(NULL
));
3782 tor_snprintf(contents
, len
,
3783 "# Tor state file last generated on %s\n"
3784 "# You *do not* need to edit this file.\n\n%s",
3787 fname
= get_or_state_fname();
3788 if (write_str_to_file(fname
, contents
, 0)<0) {
3789 log_warn(LD_FS
, "Unable to write state to file \"%s\"", fname
);
3794 log_info(LD_GENERAL
, "Saved state to \"%s\"", fname
);
3798 global_state
->dirty
= 0;
3802 /** Helper to implement GETINFO functions about configuration variables (not
3803 * their values). Given a "config/names" question, set *<b>answer</b> to a
3804 * new string describing the supported configuration variables and their
3807 config_getinfo_helper(const char *question
, char **answer
)
3809 if (!strcmp(question
, "config/names")) {
3810 smartlist_t
*sl
= smartlist_create();
3812 for (i
= 0; _option_vars
[i
].name
; ++i
) {
3813 config_var_t
*var
= &_option_vars
[i
];
3814 const char *type
, *desc
;
3817 desc
= config_find_description(&options_format
, var
->name
);
3818 switch (var
->type
) {
3819 case CONFIG_TYPE_STRING
: type
= "String"; break;
3820 case CONFIG_TYPE_UINT
: type
= "Integer"; break;
3821 case CONFIG_TYPE_INTERVAL
: type
= "TimeInterval"; break;
3822 case CONFIG_TYPE_MEMUNIT
: type
= "DataSize"; break;
3823 case CONFIG_TYPE_DOUBLE
: type
= "Float"; break;
3824 case CONFIG_TYPE_BOOL
: type
= "Boolean"; break;
3825 case CONFIG_TYPE_ISOTIME
: type
= "Time"; break;
3826 case CONFIG_TYPE_CSV
: type
= "CommaList"; break;
3827 case CONFIG_TYPE_LINELIST
: type
= "LineList"; break;
3828 case CONFIG_TYPE_LINELIST_S
: type
= "Dependant"; break;
3829 case CONFIG_TYPE_LINELIST_V
: type
= "Virtual"; break;
3831 case CONFIG_TYPE_OBSOLETE
:
3836 len
= strlen(var
->name
)+strlen(type
)+16;
3838 len
+= strlen(desc
);
3839 line
= tor_malloc(len
);
3841 tor_snprintf(line
, len
, "%s %s %s\n",var
->name
,type
,desc
);
3843 tor_snprintf(line
, len
, "%s %s\n",var
->name
,type
);
3844 smartlist_add(sl
, line
);
3846 *answer
= smartlist_join_strings(sl
, "", 0, NULL
);
3847 SMARTLIST_FOREACH(sl
, char *, c
, tor_free(c
));
3853 #include "../common/ht.h"
3854 #include "../common/test.h"
3856 /** Dump the version of every file to the log. */
3858 print_cvs_version(void)
3860 extern const char aes_c_id
[];
3861 extern const char compat_c_id
[];
3862 extern const char container_c_id
[];
3863 extern const char crypto_c_id
[];
3864 extern const char log_c_id
[];
3865 extern const char torgzip_c_id
[];
3866 extern const char tortls_c_id
[];
3867 extern const char util_c_id
[];
3869 extern const char buffers_c_id
[];
3870 extern const char circuitbuild_c_id
[];
3871 extern const char circuitlist_c_id
[];
3872 extern const char circuituse_c_id
[];
3873 extern const char command_c_id
[];
3874 // extern const char config_c_id[];
3875 extern const char connection_c_id
[];
3876 extern const char connection_edge_c_id
[];
3877 extern const char connection_or_c_id
[];
3878 extern const char control_c_id
[];
3879 extern const char cpuworker_c_id
[];
3880 extern const char directory_c_id
[];
3881 extern const char dirserv_c_id
[];
3882 extern const char dns_c_id
[];
3883 extern const char hibernate_c_id
[];
3884 extern const char main_c_id
[];
3885 extern const char onion_c_id
[];
3886 extern const char policies_c_id
[];
3887 extern const char relay_c_id
[];
3888 extern const char rendclient_c_id
[];
3889 extern const char rendcommon_c_id
[];
3890 extern const char rendmid_c_id
[];
3891 extern const char rendservice_c_id
[];
3892 extern const char rephist_c_id
[];
3893 extern const char router_c_id
[];
3894 extern const char routerlist_c_id
[];
3895 extern const char routerparse_c_id
[];
3899 puts(CONTAINER_H_ID
);
3910 puts(container_c_id
);
3919 puts(circuitbuild_c_id
);
3920 puts(circuitlist_c_id
);
3921 puts(circuituse_c_id
);
3924 puts(connection_c_id
);
3925 puts(connection_edge_c_id
);
3926 puts(connection_or_c_id
);
3928 puts(cpuworker_c_id
);
3929 puts(directory_c_id
);
3932 puts(hibernate_c_id
);
3935 puts(policies_c_id
);
3937 puts(rendclient_c_id
);
3938 puts(rendcommon_c_id
);
3940 puts(rendservice_c_id
);
3943 puts(routerlist_c_id
);
3944 puts(routerparse_c_id
);