1 /* Copyright (c) 2001 Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2009, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
9 * \brief Code to parse and interpret configuration files.
12 #define CONFIG_PRIVATE
19 /** Enumeration of types which option values can take */
20 typedef enum config_type_t
{
21 CONFIG_TYPE_STRING
= 0, /**< An arbitrary string. */
22 CONFIG_TYPE_FILENAME
, /**< A filename: some prefixes get expanded. */
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-formatted 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_ROUTERSET
, /**< A list of router names, addrs, and fps,
38 * parsed into a routerset_t. */
39 CONFIG_TYPE_OBSOLETE
, /**< Obsolete (ignored) option. */
42 /** An abbreviation for a configuration option allowed on the command line. */
43 typedef struct config_abbrev_t
{
44 const char *abbreviated
;
50 /* Handy macro for declaring "In the config file or on the command line,
51 * you can abbreviate <b>tok</b>s as <b>tok</b>". */
52 #define PLURAL(tok) { #tok, #tok "s", 0, 0 }
54 /** A list of abbreviations and aliases to map command-line options, obsolete
55 * option names, or alternative option names, to their current values. */
56 static config_abbrev_t _option_abbrevs
[] = {
61 PLURAL(LongLivedPort
),
62 PLURAL(HiddenServiceNode
),
63 PLURAL(HiddenServiceExcludeNode
),
66 PLURAL(RendExcludeNode
),
67 PLURAL(StrictEntryNode
),
68 PLURAL(StrictExitNode
),
71 { "AllowUnverifiedNodes", "AllowInvalidNodes", 0, 0},
72 { "AutomapHostSuffixes", "AutomapHostsSuffixes", 0, 0},
73 { "AutomapHostOnResolve", "AutomapHostsOnResolve", 0, 0},
74 { "BandwidthRateBytes", "BandwidthRate", 0, 0},
75 { "BandwidthBurstBytes", "BandwidthBurst", 0, 0},
76 { "DirFetchPostPeriod", "StatusFetchPeriod", 0, 0},
77 { "MaxConn", "ConnLimit", 0, 1},
78 { "ORBindAddress", "ORListenAddress", 0, 0},
79 { "DirBindAddress", "DirListenAddress", 0, 0},
80 { "SocksBindAddress", "SocksListenAddress", 0, 0},
81 { "UseHelperNodes", "UseEntryGuards", 0, 0},
82 { "NumHelperNodes", "NumEntryGuards", 0, 0},
83 { "UseEntryNodes", "UseEntryGuards", 0, 0},
84 { "NumEntryNodes", "NumEntryGuards", 0, 0},
85 { "ResolvConf", "ServerDNSResolvConfFile", 0, 1},
86 { "SearchDomains", "ServerDNSSearchDomains", 0, 1},
87 { "ServerDNSAllowBrokenResolvConf", "ServerDNSAllowBrokenConfig", 0, 0},
88 { "PreferTunnelledDirConns", "PreferTunneledDirConns", 0, 0},
89 { "BridgeAuthoritativeDirectory", "BridgeAuthoritativeDir", 0, 0},
90 { "HashedControlPassword", "__HashedControlSessionPassword", 1, 0},
91 { "StrictEntryNodes", "StrictNodes", 0, 1},
92 { "StrictExitNodes", "StrictNodes", 0, 1},
96 /** A list of state-file "abbreviations," for compatibility. */
97 static config_abbrev_t _state_abbrevs
[] = {
98 { "AccountingBytesReadInterval", "AccountingBytesReadInInterval", 0, 0 },
99 { "HelperNode", "EntryGuard", 0, 0 },
100 { "HelperNodeDownSince", "EntryGuardDownSince", 0, 0 },
101 { "HelperNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
102 { "EntryNode", "EntryGuard", 0, 0 },
103 { "EntryNodeDownSince", "EntryGuardDownSince", 0, 0 },
104 { "EntryNodeUnlistedSince", "EntryGuardUnlistedSince", 0, 0 },
109 /** A variable allowed in the configuration file or on the command line. */
110 typedef struct config_var_t
{
111 const char *name
; /**< The full keyword (case insensitive). */
112 config_type_t type
; /**< How to interpret the type and turn it into a
114 off_t var_offset
; /**< Offset of the corresponding member of or_options_t. */
115 const char *initvalue
; /**< String (or null) describing initial value. */
118 /** An entry for config_vars: "The option <b>name</b> has type
119 * CONFIG_TYPE_<b>conftype</b>, and corresponds to
120 * or_options_t.<b>member</b>"
122 #define VAR(name,conftype,member,initvalue) \
123 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_options_t, member), \
125 /** As VAR, but the option name and member name are the same. */
126 #define V(member,conftype,initvalue) \
127 VAR(#member, conftype, member, initvalue)
128 /** An entry for config_vars: "The option <b>name</b> is obsolete." */
129 #define OBSOLETE(name) { name, CONFIG_TYPE_OBSOLETE, 0, NULL }
131 /** Array of configuration options. Until we disallow nonstandard
132 * abbreviations, order is significant, since the first matching option will
135 static config_var_t _option_vars
[] = {
136 OBSOLETE("AccountingMaxKB"),
137 V(AccountingMax
, MEMUNIT
, "0 bytes"),
138 V(AccountingStart
, STRING
, NULL
),
139 V(Address
, STRING
, NULL
),
140 V(AllowDotExit
, BOOL
, "0"),
141 V(AllowInvalidNodes
, CSV
, "middle,rendezvous"),
142 V(AllowNonRFC953Hostnames
, BOOL
, "0"),
143 V(AllowSingleHopCircuits
, BOOL
, "0"),
144 V(AllowSingleHopExits
, BOOL
, "0"),
145 V(AlternateBridgeAuthority
, LINELIST
, NULL
),
146 V(AlternateDirAuthority
, LINELIST
, NULL
),
147 V(AlternateHSAuthority
, LINELIST
, NULL
),
148 V(AssumeReachable
, BOOL
, "0"),
149 V(AuthDirBadDir
, LINELIST
, NULL
),
150 V(AuthDirBadExit
, LINELIST
, NULL
),
151 V(AuthDirInvalid
, LINELIST
, NULL
),
152 V(AuthDirReject
, LINELIST
, NULL
),
153 V(AuthDirRejectUnlisted
, BOOL
, "0"),
154 V(AuthDirListBadDirs
, BOOL
, "0"),
155 V(AuthDirListBadExits
, BOOL
, "0"),
156 V(AuthDirMaxServersPerAddr
, UINT
, "2"),
157 V(AuthDirMaxServersPerAuthAddr
,UINT
, "5"),
158 VAR("AuthoritativeDirectory", BOOL
, AuthoritativeDir
, "0"),
159 V(AutomapHostsOnResolve
, BOOL
, "0"),
160 V(AutomapHostsSuffixes
, CSV
, ".onion,.exit"),
161 V(AvoidDiskWrites
, BOOL
, "0"),
162 V(BandwidthBurst
, MEMUNIT
, "10 MB"),
163 V(BandwidthRate
, MEMUNIT
, "5 MB"),
164 V(BridgeAuthoritativeDir
, BOOL
, "0"),
165 VAR("Bridge", LINELIST
, Bridges
, NULL
),
166 V(BridgePassword
, STRING
, NULL
),
167 V(BridgeRecordUsageByCountry
, BOOL
, "1"),
168 V(BridgeRelay
, BOOL
, "0"),
169 V(CellStatistics
, BOOL
, "0"),
170 V(CircuitBuildTimeout
, INTERVAL
, "0"),
171 V(CircuitIdleTimeout
, INTERVAL
, "1 hour"),
172 V(CircuitStreamTimeout
, INTERVAL
, "0"),
173 V(CircuitPriorityHalflife
, DOUBLE
, "-100.0"), /*negative:'Use default'*/
174 V(ClientDNSRejectInternalAddresses
, BOOL
,"1"),
175 V(ClientOnly
, BOOL
, "0"),
176 V(ConsensusParams
, STRING
, NULL
),
177 V(ConnLimit
, UINT
, "1000"),
178 V(ConstrainedSockets
, BOOL
, "0"),
179 V(ConstrainedSockSize
, MEMUNIT
, "8192"),
180 V(ContactInfo
, STRING
, NULL
),
181 V(ControlListenAddress
, LINELIST
, NULL
),
182 V(ControlPort
, UINT
, "0"),
183 V(ControlSocket
, LINELIST
, NULL
),
184 V(CookieAuthentication
, BOOL
, "0"),
185 V(CookieAuthFileGroupReadable
, BOOL
, "0"),
186 V(CookieAuthFile
, STRING
, NULL
),
187 V(DataDirectory
, FILENAME
, NULL
),
188 OBSOLETE("DebugLogFile"),
189 V(DirAllowPrivateAddresses
, BOOL
, NULL
),
190 V(TestingAuthDirTimeToLearnReachability
, INTERVAL
, "30 minutes"),
191 V(DirListenAddress
, LINELIST
, NULL
),
192 OBSOLETE("DirFetchPeriod"),
193 V(DirPolicy
, LINELIST
, NULL
),
194 V(DirPort
, UINT
, "0"),
195 V(DirPortFrontPage
, FILENAME
, NULL
),
196 OBSOLETE("DirPostPeriod"),
197 OBSOLETE("DirRecordUsageByCountry"),
198 OBSOLETE("DirRecordUsageGranularity"),
199 OBSOLETE("DirRecordUsageRetainIPs"),
200 OBSOLETE("DirRecordUsageSaveInterval"),
201 V(DirReqStatistics
, BOOL
, "0"),
202 VAR("DirServer", LINELIST
, DirServers
, NULL
),
203 V(DisableAllSwap
, BOOL
, "0"),
204 V(DNSPort
, UINT
, "0"),
205 V(DNSListenAddress
, LINELIST
, NULL
),
206 V(DownloadExtraInfo
, BOOL
, "0"),
207 V(EnforceDistinctSubnets
, BOOL
, "1"),
208 V(EntryNodes
, ROUTERSET
, NULL
),
209 V(EntryStatistics
, BOOL
, "0"),
210 V(TestingEstimatedDescriptorPropagationTime
, INTERVAL
, "10 minutes"),
211 V(ExcludeNodes
, ROUTERSET
, NULL
),
212 V(ExcludeExitNodes
, ROUTERSET
, NULL
),
213 V(ExcludeSingleHopRelays
, BOOL
, "1"),
214 V(ExitNodes
, ROUTERSET
, NULL
),
215 V(ExitPolicy
, LINELIST
, NULL
),
216 V(ExitPolicyRejectPrivate
, BOOL
, "1"),
217 V(ExitPortStatistics
, BOOL
, "0"),
218 V(ExtraInfoStatistics
, BOOL
, "0"),
220 V(FallbackNetworkstatusFile
, FILENAME
,
221 SHARE_DATADIR PATH_SEPARATOR
"tor" PATH_SEPARATOR
"fallback-consensus"),
222 V(FascistFirewall
, BOOL
, "0"),
223 V(FirewallPorts
, CSV
, ""),
224 V(FastFirstHopPK
, BOOL
, "1"),
225 V(FetchDirInfoEarly
, BOOL
, "0"),
226 V(FetchDirInfoExtraEarly
, BOOL
, "0"),
227 V(FetchServerDescriptors
, BOOL
, "1"),
228 V(FetchHidServDescriptors
, BOOL
, "1"),
229 V(FetchUselessDescriptors
, BOOL
, "0"),
231 V(GeoIPFile
, FILENAME
, "<default>"),
233 V(GeoIPFile
, FILENAME
,
234 SHARE_DATADIR PATH_SEPARATOR
"tor" PATH_SEPARATOR
"geoip"),
237 V(HardwareAccel
, BOOL
, "0"),
238 V(AccelName
, STRING
, NULL
),
239 V(AccelDir
, FILENAME
, NULL
),
240 V(HashedControlPassword
, LINELIST
, NULL
),
241 V(HidServDirectoryV2
, BOOL
, "1"),
242 VAR("HiddenServiceDir", LINELIST_S
, RendConfigLines
, NULL
),
243 OBSOLETE("HiddenServiceExcludeNodes"),
244 OBSOLETE("HiddenServiceNodes"),
245 VAR("HiddenServiceOptions",LINELIST_V
, RendConfigLines
, NULL
),
246 VAR("HiddenServicePort", LINELIST_S
, RendConfigLines
, NULL
),
247 VAR("HiddenServiceVersion",LINELIST_S
, RendConfigLines
, NULL
),
248 VAR("HiddenServiceAuthorizeClient",LINELIST_S
,RendConfigLines
, NULL
),
249 V(HidServAuth
, LINELIST
, NULL
),
250 V(HSAuthoritativeDir
, BOOL
, "0"),
251 OBSOLETE("HSAuthorityRecordStats"),
252 V(HttpProxy
, STRING
, NULL
),
253 V(HttpProxyAuthenticator
, STRING
, NULL
),
254 V(HttpsProxy
, STRING
, NULL
),
255 V(HttpsProxyAuthenticator
, STRING
, NULL
),
256 V(Socks4Proxy
, STRING
, NULL
),
257 V(Socks5Proxy
, STRING
, NULL
),
258 V(Socks5ProxyUsername
, STRING
, NULL
),
259 V(Socks5ProxyPassword
, STRING
, NULL
),
260 OBSOLETE("IgnoreVersion"),
261 V(KeepalivePeriod
, INTERVAL
, "5 minutes"),
262 VAR("Log", LINELIST
, Logs
, NULL
),
263 OBSOLETE("LinkPadding"),
264 OBSOLETE("LogLevel"),
266 V(LongLivedPorts
, CSV
,
267 "21,22,706,1863,5050,5190,5222,5223,6667,6697,8300"),
268 VAR("MapAddress", LINELIST
, AddressMap
, NULL
),
269 V(MaxAdvertisedBandwidth
, MEMUNIT
, "1 GB"),
270 V(MaxCircuitDirtiness
, INTERVAL
, "10 minutes"),
271 V(MaxOnionsPending
, UINT
, "100"),
272 OBSOLETE("MonthlyAccountingStart"),
273 V(MyFamily
, STRING
, NULL
),
274 V(NewCircuitPeriod
, INTERVAL
, "30 seconds"),
275 VAR("NamingAuthoritativeDirectory",BOOL
, NamingAuthoritativeDir
, "0"),
276 V(NatdListenAddress
, LINELIST
, NULL
),
277 V(NatdPort
, UINT
, "0"),
278 V(Nickname
, STRING
, NULL
),
279 V(NoPublish
, BOOL
, "0"),
280 VAR("NodeFamily", LINELIST
, NodeFamilies
, NULL
),
281 V(NumCpus
, UINT
, "1"),
282 V(NumEntryGuards
, UINT
, "3"),
283 V(ORListenAddress
, LINELIST
, NULL
),
284 V(ORPort
, UINT
, "0"),
285 V(OutboundBindAddress
, STRING
, NULL
),
286 OBSOLETE("PathlenCoinWeight"),
287 V(PidFile
, STRING
, NULL
),
288 V(TestingTorNetwork
, BOOL
, "0"),
289 V(PreferTunneledDirConns
, BOOL
, "1"),
290 V(ProtocolWarnings
, BOOL
, "0"),
291 V(PublishServerDescriptor
, CSV
, "1"),
292 V(PublishHidServDescriptors
, BOOL
, "1"),
293 V(ReachableAddresses
, LINELIST
, NULL
),
294 V(ReachableDirAddresses
, LINELIST
, NULL
),
295 V(ReachableORAddresses
, LINELIST
, NULL
),
296 V(RecommendedVersions
, LINELIST
, NULL
),
297 V(RecommendedClientVersions
, LINELIST
, NULL
),
298 V(RecommendedServerVersions
, LINELIST
, NULL
),
299 OBSOLETE("RedirectExit"),
300 V(RejectPlaintextPorts
, CSV
, ""),
301 V(RelayBandwidthBurst
, MEMUNIT
, "0"),
302 V(RelayBandwidthRate
, MEMUNIT
, "0"),
303 OBSOLETE("RendExcludeNodes"),
304 OBSOLETE("RendNodes"),
305 V(RendPostPeriod
, INTERVAL
, "1 hour"),
306 V(RephistTrackTime
, INTERVAL
, "24 hours"),
307 OBSOLETE("RouterFile"),
308 V(RunAsDaemon
, BOOL
, "0"),
309 V(RunTesting
, BOOL
, "0"),
310 V(SafeLogging
, STRING
, "1"),
311 V(SafeSocks
, BOOL
, "0"),
312 V(ServerDNSAllowBrokenConfig
, BOOL
, "1"),
313 V(ServerDNSAllowNonRFC953Hostnames
, BOOL
,"0"),
314 V(ServerDNSDetectHijacking
, BOOL
, "1"),
315 V(ServerDNSRandomizeCase
, BOOL
, "1"),
316 V(ServerDNSResolvConfFile
, STRING
, NULL
),
317 V(ServerDNSSearchDomains
, BOOL
, "0"),
318 V(ServerDNSTestAddresses
, CSV
,
319 "www.google.com,www.mit.edu,www.yahoo.com,www.slashdot.org"),
320 V(ShutdownWaitLength
, INTERVAL
, "30 seconds"),
321 V(SocksListenAddress
, LINELIST
, NULL
),
322 V(SocksPolicy
, LINELIST
, NULL
),
323 V(SocksPort
, UINT
, "9050"),
324 V(SocksTimeout
, INTERVAL
, "2 minutes"),
325 OBSOLETE("StatusFetchPeriod"),
326 V(StrictNodes
, BOOL
, "0"),
328 V(TestSocks
, BOOL
, "0"),
330 V(TrackHostExits
, CSV
, NULL
),
331 V(TrackHostExitsExpire
, INTERVAL
, "30 minutes"),
332 OBSOLETE("TrafficShaping"),
333 V(TransListenAddress
, LINELIST
, NULL
),
334 V(TransPort
, UINT
, "0"),
335 V(TunnelDirConns
, BOOL
, "1"),
336 V(UpdateBridgesFromAuthority
, BOOL
, "0"),
337 V(UseBridges
, BOOL
, "0"),
338 V(UseEntryGuards
, BOOL
, "1"),
339 V(User
, STRING
, NULL
),
340 VAR("V1AuthoritativeDirectory",BOOL
, V1AuthoritativeDir
, "0"),
341 VAR("V2AuthoritativeDirectory",BOOL
, V2AuthoritativeDir
, "0"),
342 VAR("V3AuthoritativeDirectory",BOOL
, V3AuthoritativeDir
, "0"),
343 V(TestingV3AuthInitialVotingInterval
, INTERVAL
, "30 minutes"),
344 V(TestingV3AuthInitialVoteDelay
, INTERVAL
, "5 minutes"),
345 V(TestingV3AuthInitialDistDelay
, INTERVAL
, "5 minutes"),
346 V(V3AuthVotingInterval
, INTERVAL
, "1 hour"),
347 V(V3AuthVoteDelay
, INTERVAL
, "5 minutes"),
348 V(V3AuthDistDelay
, INTERVAL
, "5 minutes"),
349 V(V3AuthNIntervalsValid
, UINT
, "3"),
350 V(V3AuthUseLegacyKey
, BOOL
, "0"),
351 V(V3BandwidthsFile
, FILENAME
, NULL
),
352 VAR("VersioningAuthoritativeDirectory",BOOL
,VersioningAuthoritativeDir
, "0"),
353 V(VirtualAddrNetwork
, STRING
, "127.192.0.0/10"),
354 V(WarnPlaintextPorts
, CSV
, "23,109,110,143"),
355 VAR("__ReloadTorrcOnSIGHUP", BOOL
, ReloadTorrcOnSIGHUP
, "1"),
356 VAR("__AllDirActionsPrivate", BOOL
, AllDirActionsPrivate
, "0"),
357 VAR("__DisablePredictedCircuits",BOOL
,DisablePredictedCircuits
, "0"),
358 VAR("__LeaveStreamsUnattached",BOOL
, LeaveStreamsUnattached
, "0"),
359 VAR("__HashedControlSessionPassword", LINELIST
, HashedControlSessionPassword
,
361 V(MinUptimeHidServDirectoryV2
, INTERVAL
, "24 hours"),
363 { NULL
, CONFIG_TYPE_OBSOLETE
, 0, NULL
}
366 /** Override default values with these if the user sets the TestingTorNetwork
368 static config_var_t testing_tor_network_defaults
[] = {
369 V(ServerDNSAllowBrokenConfig
, BOOL
, "1"),
370 V(DirAllowPrivateAddresses
, BOOL
, "1"),
371 V(EnforceDistinctSubnets
, BOOL
, "0"),
372 V(AssumeReachable
, BOOL
, "1"),
373 V(AuthDirMaxServersPerAddr
, UINT
, "0"),
374 V(AuthDirMaxServersPerAuthAddr
,UINT
, "0"),
375 V(ClientDNSRejectInternalAddresses
, BOOL
,"0"),
376 V(ExitPolicyRejectPrivate
, BOOL
, "0"),
377 V(V3AuthVotingInterval
, INTERVAL
, "5 minutes"),
378 V(V3AuthVoteDelay
, INTERVAL
, "20 seconds"),
379 V(V3AuthDistDelay
, INTERVAL
, "20 seconds"),
380 V(TestingV3AuthInitialVotingInterval
, INTERVAL
, "5 minutes"),
381 V(TestingV3AuthInitialVoteDelay
, INTERVAL
, "20 seconds"),
382 V(TestingV3AuthInitialDistDelay
, INTERVAL
, "20 seconds"),
383 V(TestingAuthDirTimeToLearnReachability
, INTERVAL
, "0 minutes"),
384 V(TestingEstimatedDescriptorPropagationTime
, INTERVAL
, "0 minutes"),
385 { NULL
, CONFIG_TYPE_OBSOLETE
, 0, NULL
}
389 #define VAR(name,conftype,member,initvalue) \
390 { name, CONFIG_TYPE_ ## conftype, STRUCT_OFFSET(or_state_t, member), \
393 /** Array of "state" variables saved to the ~/.tor/state file. */
394 static config_var_t _state_vars
[] = {
395 V(AccountingBytesReadInInterval
, MEMUNIT
, NULL
),
396 V(AccountingBytesWrittenInInterval
, MEMUNIT
, NULL
),
397 V(AccountingExpectedUsage
, MEMUNIT
, NULL
),
398 V(AccountingIntervalStart
, ISOTIME
, NULL
),
399 V(AccountingSecondsActive
, INTERVAL
, NULL
),
401 VAR("EntryGuard", LINELIST_S
, EntryGuards
, NULL
),
402 VAR("EntryGuardDownSince", LINELIST_S
, EntryGuards
, NULL
),
403 VAR("EntryGuardUnlistedSince", LINELIST_S
, EntryGuards
, NULL
),
404 VAR("EntryGuardAddedBy", LINELIST_S
, EntryGuards
, NULL
),
405 V(EntryGuards
, LINELIST_V
, NULL
),
407 V(BWHistoryReadEnds
, ISOTIME
, NULL
),
408 V(BWHistoryReadInterval
, UINT
, "900"),
409 V(BWHistoryReadValues
, CSV
, ""),
410 V(BWHistoryWriteEnds
, ISOTIME
, NULL
),
411 V(BWHistoryWriteInterval
, UINT
, "900"),
412 V(BWHistoryWriteValues
, CSV
, ""),
414 V(TorVersion
, STRING
, NULL
),
416 V(LastRotatedOnionKey
, ISOTIME
, NULL
),
417 V(LastWritten
, ISOTIME
, NULL
),
419 V(TotalBuildTimes
, UINT
, NULL
),
420 VAR("CircuitBuildTimeBin", LINELIST_S
, BuildtimeHistogram
, NULL
),
421 VAR("BuildtimeHistogram", LINELIST_V
, BuildtimeHistogram
, NULL
),
423 { NULL
, CONFIG_TYPE_OBSOLETE
, 0, NULL
}
430 /** Represents an English description of a configuration variable; used when
431 * generating configuration file comments. */
432 typedef struct config_var_description_t
{
434 const char *description
;
435 } config_var_description_t
;
437 /** Descriptions of the configuration options, to be displayed by online
439 /* XXXX022 did anybody want this? at all? If not, kill it.*/
440 static config_var_description_t options_description
[] = {
441 /* ==== general options */
442 { "AvoidDiskWrites", "If non-zero, try to write to disk less frequently than"
443 " we would otherwise." },
444 { "BandwidthRate", "A token bucket limits the average incoming bandwidth on "
445 "this node to the specified number of bytes per second." },
446 { "BandwidthBurst", "Limit the maximum token buffer size (also known as "
447 "burst) to the given number of bytes." },
448 { "ConnLimit", "Minimum number of simultaneous sockets we must have." },
449 { "ConstrainedSockets", "Shrink tx and rx buffers for sockets to avoid "
450 "system limits on vservers and related environments. See man page for "
451 "more information regarding this option." },
452 { "ConstrainedSockSize", "Limit socket buffers to this size when "
453 "ConstrainedSockets is enabled." },
454 /* ControlListenAddress */
455 { "ControlPort", "If set, Tor will accept connections from the same machine "
456 "(localhost only) on this port, and allow those connections to control "
457 "the Tor process using the Tor Control Protocol (described in "
458 "control-spec.txt).", },
459 { "CookieAuthentication", "If this option is set to 1, don't allow any "
460 "connections to the control port except when the connecting process "
461 "can read a file that Tor creates in its data directory." },
462 { "DataDirectory", "Store working data, state, keys, and caches here." },
463 { "DirServer", "Tor only trusts directories signed with one of these "
464 "servers' keys. Used to override the standard list of directory "
466 { "DisableAllSwap", "Tor will attempt a simple memory lock that "
467 "will prevent leaking of all information in memory to the swap file." },
468 /* { "FastFirstHopPK", "" }, */
469 /* FetchServerDescriptors, FetchHidServDescriptors,
470 * FetchUselessDescriptors */
471 { "HardwareAccel", "If set, Tor tries to use hardware crypto accelerators "
473 { "AccelName", "If set, try to use hardware crypto accelerator with this "
475 { "AccelDir", "If set, look in this directory for the dynamic hardware "
476 "engine in addition to OpenSSL default path." },
477 /* HashedControlPassword */
478 { "HTTPProxy", "Force Tor to make all HTTP directory requests through this "
479 "host:port (or host:80 if port is not set)." },
480 { "HTTPProxyAuthenticator", "A username:password pair to be used with "
482 { "HTTPSProxy", "Force Tor to make all TLS (SSL) connections through this "
483 "host:port (or host:80 if port is not set)." },
484 { "HTTPSProxyAuthenticator", "A username:password pair to be used with "
486 { "KeepalivePeriod", "Send a padding cell every N seconds to keep firewalls "
487 "from closing our connections while Tor is not in use." },
488 { "Log", "Where to send logging messages. Format is "
489 "minSeverity[-maxSeverity] (stderr|stdout|syslog|file FILENAME)." },
490 { "OutboundBindAddress", "Make all outbound connections originate from the "
491 "provided IP address (only useful for multiple network interfaces)." },
492 { "PIDFile", "On startup, write our PID to this file. On clean shutdown, "
493 "remove the file." },
494 { "PreferTunneledDirConns", "If non-zero, avoid directory servers that "
495 "don't support tunneled connections." },
496 /* PreferTunneledDirConns */
497 /* ProtocolWarnings */
498 /* RephistTrackTime */
499 { "RunAsDaemon", "If set, Tor forks and daemonizes to the background when "
500 "started. Unix only." },
501 { "SafeLogging", "If set to 0, Tor logs potentially sensitive strings "
502 "rather than replacing them with the string [scrubbed]." },
503 { "TunnelDirConns", "If non-zero, when a directory server we contact "
504 "supports it, we will build a one-hop circuit and make an encrypted "
505 "connection via its ORPort." },
506 { "User", "On startup, setuid to this user." },
508 /* ==== client options */
509 { "AllowInvalidNodes", "Where on our circuits should Tor allow servers "
510 "that the directory authorities haven't called \"valid\"?" },
511 { "AllowNonRFC953Hostnames", "If set to 1, we don't automatically reject "
512 "hostnames for having invalid characters." },
513 /* CircuitBuildTimeout, CircuitIdleTimeout */
514 { "ClientOnly", "If set to 1, Tor will under no circumstances run as a "
515 "server, even if ORPort is enabled." },
516 { "EntryNodes", "A list of preferred entry nodes to use for the first hop "
517 "in circuits, when possible." },
518 /* { "EnforceDistinctSubnets" , "" }, */
519 { "ExitNodes", "A list of preferred nodes to use for the last hop in "
520 "circuits, when possible." },
521 { "ExcludeNodes", "A list of nodes never to use when building a circuit." },
522 { "ExcludeExitNodes", "A list of nodes never to use for the last when "
523 "building a circuit for exit. Other circuits can still end at these "
525 { "FascistFirewall", "If set, Tor will only create outgoing connections to "
526 "servers running on the ports listed in FirewallPorts." },
527 { "FirewallPorts", "A list of ports that we can connect to. Only used "
528 "when FascistFirewall is set." },
529 { "LongLivedPorts", "A list of ports for services that tend to require "
530 "high-uptime connections." },
531 { "MapAddress", "Force Tor to treat all requests for one address as if "
532 "they were for another." },
533 { "NewCircuitPeriod", "Force Tor to consider whether to build a new circuit "
534 "every NUM seconds." },
535 { "MaxCircuitDirtiness", "Do not attach new streams to a circuit that has "
536 "been used more than this many seconds ago." },
537 /* NatdPort, NatdListenAddress */
538 { "NodeFamily", "A list of servers that constitute a 'family' and should "
539 "never be used in the same circuit." },
540 { "NumEntryGuards", "How many entry guards should we keep at a time?" },
541 /* PathlenCoinWeight */
542 { "ReachableAddresses", "Addresses we can connect to, as IP/bits:port-port. "
543 "By default, we assume all addresses are reachable." },
544 /* reachablediraddresses, reachableoraddresses. */
546 { "SOCKSPort", "The port where we listen for SOCKS connections from "
548 { "SOCKSListenAddress", "Bind to this address to listen to connections from "
549 "SOCKS-speaking applications." },
550 { "SOCKSPolicy", "Set an entry policy to limit which addresses can connect "
551 "to the SOCKSPort." },
553 { "StrictNodes", "If set, Tor will fail to operate when none of the "
554 "configured EntryNodes, ExitNodes, ExcludeNodes, or ExcludeExitNodes "
557 { "TrackHostsExit", "Hosts and domains which should, if possible, be "
558 "accessed from the same exit node each time we connect to them." },
559 { "TrackHostsExitExpire", "Time after which we forget which exit we were "
560 "using to connect to hosts in TrackHostsExit." },
561 /* "TransPort", "TransListenAddress */
562 { "UseEntryGuards", "Set to 0 if we want to pick from the whole set of "
563 "servers for the first position in each circuit, rather than picking a "
564 "set of 'Guards' to prevent profiling attacks." },
566 /* === server options */
567 { "Address", "The advertised (external) address we should use." },
568 /* Accounting* options. */
569 /* AssumeReachable */
570 { "ContactInfo", "Administrative contact information to advertise for this "
572 { "ExitPolicy", "Address/port ranges for which to accept or reject outgoing "
573 "connections on behalf of Tor users." },
574 /* { "ExitPolicyRejectPrivate, "" }, */
575 { "MaxAdvertisedBandwidth", "If set, we will not advertise more than this "
576 "amount of bandwidth for our bandwidth rate, regardless of how much "
577 "bandwidth we actually detect." },
578 { "MaxOnionsPending", "Reject new attempts to extend circuits when we "
579 "already have this many pending." },
580 { "MyFamily", "Declare a list of other servers as belonging to the same "
581 "family as this one, so that clients will not use two from the same "
582 "family in the same circuit." },
583 { "Nickname", "Set the server nickname." },
584 { "NoPublish", "{DEPRECATED}" },
585 { "NumCPUs", "How many processes to use at once for public-key crypto." },
586 { "ORPort", "Advertise this port to listen for connections from Tor clients "
588 { "ORListenAddress", "Bind to this address to listen for connections from "
589 "clients and servers, instead of the default 0.0.0.0:ORPort." },
590 { "PublishServerDescriptor", "Set to 0 to keep the server from "
591 "uploading info to the directory authorities." },
592 /* ServerDNS: DetectHijacking, ResolvConfFile, SearchDomains */
593 { "ShutdownWaitLength", "Wait this long for clients to finish when "
594 "shutting down because of a SIGINT." },
596 /* === directory cache options */
597 { "DirPort", "Serve directory information from this port, and act as a "
598 "directory cache." },
599 { "DirPortFrontPage", "Serve a static html disclaimer on DirPort." },
600 { "DirListenAddress", "Bind to this address to listen for connections from "
601 "clients and servers, instead of the default 0.0.0.0:DirPort." },
602 { "DirPolicy", "Set a policy to limit who can connect to the directory "
605 /* Authority options: AuthDirBadExit, AuthDirInvalid, AuthDirReject,
606 * AuthDirRejectUnlisted, AuthDirListBadExits, AuthoritativeDirectory,
607 * DirAllowPrivateAddresses, HSAuthoritativeDir,
608 * NamingAuthoritativeDirectory, RecommendedVersions,
609 * RecommendedClientVersions, RecommendedServerVersions, RendPostPeriod,
610 * RunTesting, V1AuthoritativeDirectory, VersioningAuthoritativeDirectory, */
612 /* Hidden service options: HiddenService: dir,excludenodes, nodes,
613 * options, port. PublishHidServDescriptor */
615 /* Circuit build time histogram options */
616 { "CircuitBuildTimeBin", "Histogram of recent circuit build times"},
617 { "TotalBuildTimes", "Total number of buildtimes in histogram"},
619 /* Nonpersistent options: __LeaveStreamsUnattached, __AllDirActionsPrivate */
623 /** Online description of state variables. */
624 static config_var_description_t state_description
[] = {
625 { "AccountingBytesReadInInterval",
626 "How many bytes have we read in this accounting period?" },
627 { "AccountingBytesWrittenInInterval",
628 "How many bytes have we written in this accounting period?" },
629 { "AccountingExpectedUsage",
630 "How many bytes did we expect to use per minute? (0 for no estimate.)" },
631 { "AccountingIntervalStart", "When did this accounting period begin?" },
632 { "AccountingSecondsActive", "How long have we been awake in this period?" },
634 { "BWHistoryReadEnds", "When does the last-recorded read-interval end?" },
635 { "BWHistoryReadInterval", "How long is each read-interval (in seconds)?" },
636 { "BWHistoryReadValues", "Number of bytes read in each interval." },
637 { "BWHistoryWriteEnds", "When does the last-recorded write-interval end?" },
638 { "BWHistoryWriteInterval", "How long is each write-interval (in seconds)?"},
639 { "BWHistoryWriteValues", "Number of bytes written in each interval." },
641 { "EntryGuard", "One of the nodes we have chosen as a fixed entry" },
642 { "EntryGuardDownSince",
643 "The last entry guard has been unreachable since this time." },
644 { "EntryGuardUnlistedSince",
645 "The last entry guard has been unusable since this time." },
647 { "LastRotatedOnionKey",
648 "The last time at which we changed the medium-term private key used for "
649 "building circuits." },
650 { "LastWritten", "When was this state file last regenerated?" },
652 { "TorVersion", "Which version of Tor generated this state file?" },
656 /** Type of a callback to validate whether a given configuration is
657 * well-formed and consistent. See options_trial_assign() for documentation
659 typedef int (*validate_fn_t
)(void*,void*,int,char**);
661 /** Information on the keys, value types, key-to-struct-member mappings,
662 * variable descriptions, validation functions, and abbreviations for a
663 * configuration or storage format. */
665 size_t size
; /**< Size of the struct that everything gets parsed into. */
666 uint32_t magic
; /**< Required 'magic value' to make sure we have a struct
667 * of the right type. */
668 off_t magic_offset
; /**< Offset of the magic value within the struct. */
669 config_abbrev_t
*abbrevs
; /**< List of abbreviations that we expand when
670 * parsing this format. */
671 config_var_t
*vars
; /**< List of variables we recognize, their default
672 * values, and where we stick them in the structure. */
673 validate_fn_t validate_fn
; /**< Function to validate config. */
674 /** Documentation for configuration variables. */
675 config_var_description_t
*descriptions
;
676 /** If present, extra is a LINELIST variable for unrecognized
677 * lines. Otherwise, unrecognized lines are an error. */
681 /** Macro: assert that <b>cfg</b> has the right magic field for format
683 #define CHECK(fmt, cfg) STMT_BEGIN \
684 tor_assert(fmt && cfg); \
685 tor_assert((fmt)->magic == \
686 *(uint32_t*)STRUCT_VAR_P(cfg,fmt->magic_offset)); \
690 static char *get_windows_conf_root(void);
692 static void config_line_append(config_line_t
**lst
,
693 const char *key
, const char *val
);
694 static void option_clear(config_format_t
*fmt
, or_options_t
*options
,
696 static void option_reset(config_format_t
*fmt
, or_options_t
*options
,
697 config_var_t
*var
, int use_defaults
);
698 static void config_free(config_format_t
*fmt
, void *options
);
699 static int config_lines_eq(config_line_t
*a
, config_line_t
*b
);
700 static int option_is_same(config_format_t
*fmt
,
701 or_options_t
*o1
, or_options_t
*o2
,
703 static or_options_t
*options_dup(config_format_t
*fmt
, or_options_t
*old
);
704 static int options_validate(or_options_t
*old_options
, or_options_t
*options
,
705 int from_setconf
, char **msg
);
706 static int options_act_reversible(or_options_t
*old_options
, char **msg
);
707 static int options_act(or_options_t
*old_options
);
708 static int options_transition_allowed(or_options_t
*old
, or_options_t
*new,
710 static int options_transition_affects_workers(or_options_t
*old_options
,
711 or_options_t
*new_options
);
712 static int options_transition_affects_descriptor(or_options_t
*old_options
,
713 or_options_t
*new_options
);
714 static int check_nickname_list(const char *lst
, const char *name
, char **msg
);
715 static void config_register_addressmaps(or_options_t
*options
);
717 static int parse_bridge_line(const char *line
, int validate_only
);
718 static int parse_dir_server_line(const char *line
,
719 authority_type_t required_type
,
721 static int validate_data_directory(or_options_t
*options
);
722 static int write_configuration_file(const char *fname
, or_options_t
*options
);
723 static config_line_t
*get_assigned_option(config_format_t
*fmt
,
724 void *options
, const char *key
,
726 static void config_init(config_format_t
*fmt
, void *options
);
727 static int or_state_validate(or_state_t
*old_options
, or_state_t
*options
,
728 int from_setconf
, char **msg
);
729 static int or_state_load(void);
730 static int options_init_logs(or_options_t
*options
, int validate_only
);
732 static int is_listening_on_low_port(uint16_t port_option
,
733 const config_line_t
*listen_options
);
735 static uint64_t config_parse_memunit(const char *s
, int *ok
);
736 static int config_parse_interval(const char *s
, int *ok
);
737 static void init_libevent(void);
738 static int opt_streq(const char *s1
, const char *s2
);
740 /** Magic value for or_options_t. */
741 #define OR_OPTIONS_MAGIC 9090909
743 /** Configuration format for or_options_t. */
744 static config_format_t options_format
= {
745 sizeof(or_options_t
),
747 STRUCT_OFFSET(or_options_t
, _magic
),
750 (validate_fn_t
)options_validate
,
755 /** Magic value for or_state_t. */
756 #define OR_STATE_MAGIC 0x57A73f57
758 /** "Extra" variable in the state that receives lines we can't parse. This
759 * lets us preserve options from versions of Tor newer than us. */
760 static config_var_t state_extra_var
= {
761 "__extra", CONFIG_TYPE_LINELIST
, STRUCT_OFFSET(or_state_t
, ExtraLines
), NULL
764 /** Configuration format for or_state_t. */
765 static config_format_t state_format
= {
768 STRUCT_OFFSET(or_state_t
, _magic
),
771 (validate_fn_t
)or_state_validate
,
777 * Functions to read and write the global options pointer.
780 /** Command-line and config-file options. */
781 static or_options_t
*global_options
= NULL
;
782 /** Name of most recently read torrc file. */
783 static char *torrc_fname
= NULL
;
784 /** Persistent serialized state. */
785 static or_state_t
*global_state
= NULL
;
786 /** Configuration Options set by command line. */
787 static config_line_t
*global_cmdline_options
= NULL
;
788 /** Contents of most recently read DirPortFrontPage file. */
789 static char *global_dirfrontpagecontents
= NULL
;
791 /** Return the contents of our frontpage string, or NULL if not configured. */
793 get_dirportfrontpage(void)
795 return global_dirfrontpagecontents
;
798 /** Allocate an empty configuration object of a given format type. */
800 config_alloc(config_format_t
*fmt
)
802 void *opts
= tor_malloc_zero(fmt
->size
);
803 *(uint32_t*)STRUCT_VAR_P(opts
, fmt
->magic_offset
) = fmt
->magic
;
808 /** Return the currently configured options. */
812 tor_assert(global_options
);
813 return global_options
;
816 /** Change the current global options to contain <b>new_val</b> instead of
817 * their current value; take action based on the new value; free the old value
818 * as necessary. Returns 0 on success, -1 on failure.
821 set_options(or_options_t
*new_val
, char **msg
)
823 or_options_t
*old_options
= global_options
;
824 global_options
= new_val
;
825 /* Note that we pass the *old* options below, for comparison. It
826 * pulls the new options directly out of global_options. */
827 if (options_act_reversible(old_options
, msg
)<0) {
829 global_options
= old_options
;
832 if (options_act(old_options
) < 0) { /* acting on the options failed. die. */
834 "Acting on config options left us in a broken state. Dying.");
838 config_free(&options_format
, old_options
);
843 extern const char tor_git_revision
[]; /* from tor_main.c */
845 /** The version of this Tor process, as parsed. */
846 static char *_version
= NULL
;
848 /** Return the current Tor version. */
852 if (_version
== NULL
) {
853 if (strlen(tor_git_revision
)) {
854 size_t len
= strlen(VERSION
)+strlen(tor_git_revision
)+16;
855 _version
= tor_malloc(len
);
856 tor_snprintf(_version
, len
, "%s (git-%s)", VERSION
, tor_git_revision
);
858 _version
= tor_strdup(VERSION
);
864 /** Release additional memory allocated in options
867 or_options_free(or_options_t
*options
)
872 routerset_free(options
->_ExcludeExitNodesUnion
);
873 config_free(&options_format
, options
);
876 /** Release all memory and resources held by global configuration structures.
879 config_free_all(void)
881 or_options_free(global_options
);
882 global_options
= NULL
;
884 config_free(&state_format
, global_state
);
887 config_free_lines(global_cmdline_options
);
888 global_cmdline_options
= NULL
;
890 tor_free(torrc_fname
);
892 tor_free(global_dirfrontpagecontents
);
895 /** Make <b>address</b> -- a piece of information related to our operation as
896 * a client -- safe to log according to the settings in options->SafeLogging,
899 * (We return "[scrubbed]" if SafeLogging is "1", and address otherwise.)
902 safe_str_client(const char *address
)
905 if (get_options()->_SafeLogging
== SAFELOG_SCRUB_ALL
)
911 /** Make <b>address</b> -- a piece of information of unspecified sensitivity
912 * -- safe to log according to the settings in options->SafeLogging, and
915 * (We return "[scrubbed]" if SafeLogging is anything besides "0", and address
919 safe_str(const char *address
)
922 if (get_options()->_SafeLogging
!= SAFELOG_SCRUB_NONE
)
928 /** Equivalent to escaped(safe_str_client(address)). See reentrancy note on
929 * escaped(): don't use this outside the main thread, or twice in the same
932 escaped_safe_str_client(const char *address
)
934 if (get_options()->_SafeLogging
== SAFELOG_SCRUB_ALL
)
937 return escaped(address
);
940 /** Equivalent to escaped(safe_str(address)). See reentrancy note on
941 * escaped(): don't use this outside the main thread, or twice in the same
944 escaped_safe_str(const char *address
)
946 if (get_options()->_SafeLogging
!= SAFELOG_SCRUB_NONE
)
949 return escaped(address
);
952 /** Add the default directory authorities directly into the trusted dir list,
953 * but only add them insofar as they share bits with <b>type</b>. */
955 add_default_trusted_dir_authorities(authority_type_t type
)
958 const char *dirservers
[] = {
959 "moria1 v1 orport=9001 v3ident=E2A2AF570166665D738736D0DD58169CC61D8A8B "
960 "128.31.0.39:9031 FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441",
961 "moria2 v1 orport=9002 128.31.0.34:9032 "
962 "719B E45D E224 B607 C537 07D0 E214 3E2D 423E 74CF",
963 "tor26 v1 orport=443 v3ident=14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
964 "86.59.21.38:80 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D",
965 "dizum orport=443 v3ident=E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58 "
966 "194.109.206.212:80 7EA6 EAD6 FD83 083C 538F 4403 8BBF A077 587D D755",
967 "Tonga orport=443 bridge no-v2 82.94.251.203:80 "
968 "4A0C CD2D DC79 9508 3D73 F5D6 6710 0C8A 5831 F16D",
969 "ides orport=9090 no-v2 v3ident=27B6B5996C426270A5C95488AA5BCEB6BCC86956 "
970 "216.224.124.114:9030 F397 038A DC51 3361 35E7 B80B D99C A384 4360 292B",
971 "gabelmoo orport=443 no-v2 "
972 "v3ident=81349FC1F2DBA2C2C11B45CB9706637D480AB913 "
973 "80.190.246.100:80 6833 3D07 61BC F397 A587 A0C0 B963 E4A9 E99E C4D3",
974 "dannenberg orport=443 no-v2 "
975 "v3ident=585769C78764D58426B8B52B6651A5A71137189A "
976 "213.73.91.31:80 7BE6 83E6 5D48 1413 21C5 ED92 F075 C553 64AC 7123",
977 "urras orport=80 no-v2 v3ident=80550987E1D626E3EBA5E5E75A458DE0626D088C "
978 "208.83.223.34:443 0AD3 FA88 4D18 F89E EA2D 89C0 1937 9E0E 7FD9 4417",
981 for (i
=0; dirservers
[i
]; i
++) {
982 if (parse_dir_server_line(dirservers
[i
], type
, 0)<0) {
983 log_err(LD_BUG
, "Couldn't parse internal dirserver line %s",
989 /** Look at all the config options for using alternate directory
990 * authorities, and make sure none of them are broken. Also, warn the
991 * user if we changed any dangerous ones.
994 validate_dir_authorities(or_options_t
*options
, or_options_t
*old_options
)
998 if (options
->DirServers
&&
999 (options
->AlternateDirAuthority
|| options
->AlternateBridgeAuthority
||
1000 options
->AlternateHSAuthority
)) {
1002 "You cannot set both DirServers and Alternate*Authority.");
1006 /* do we want to complain to the user about being partitionable? */
1007 if ((options
->DirServers
&&
1009 !config_lines_eq(options
->DirServers
, old_options
->DirServers
))) ||
1010 (options
->AlternateDirAuthority
&&
1012 !config_lines_eq(options
->AlternateDirAuthority
,
1013 old_options
->AlternateDirAuthority
)))) {
1015 "You have used DirServer or AlternateDirAuthority to "
1016 "specify alternate directory authorities in "
1017 "your configuration. This is potentially dangerous: it can "
1018 "make you look different from all other Tor users, and hurt "
1019 "your anonymity. Even if you've specified the same "
1020 "authorities as Tor uses by default, the defaults could "
1021 "change in the future. Be sure you know what you're doing.");
1024 /* Now go through the four ways you can configure an alternate
1025 * set of directory authorities, and make sure none are broken. */
1026 for (cl
= options
->DirServers
; cl
; cl
= cl
->next
)
1027 if (parse_dir_server_line(cl
->value
, NO_AUTHORITY
, 1)<0)
1029 for (cl
= options
->AlternateBridgeAuthority
; cl
; cl
= cl
->next
)
1030 if (parse_dir_server_line(cl
->value
, NO_AUTHORITY
, 1)<0)
1032 for (cl
= options
->AlternateDirAuthority
; cl
; cl
= cl
->next
)
1033 if (parse_dir_server_line(cl
->value
, NO_AUTHORITY
, 1)<0)
1035 for (cl
= options
->AlternateHSAuthority
; cl
; cl
= cl
->next
)
1036 if (parse_dir_server_line(cl
->value
, NO_AUTHORITY
, 1)<0)
1041 /** Look at all the config options and assign new dir authorities
1045 consider_adding_dir_authorities(or_options_t
*options
,
1046 or_options_t
*old_options
)
1049 int need_to_update
=
1050 !smartlist_len(router_get_trusted_dir_servers()) || !old_options
||
1051 !config_lines_eq(options
->DirServers
, old_options
->DirServers
) ||
1052 !config_lines_eq(options
->AlternateBridgeAuthority
,
1053 old_options
->AlternateBridgeAuthority
) ||
1054 !config_lines_eq(options
->AlternateDirAuthority
,
1055 old_options
->AlternateDirAuthority
) ||
1056 !config_lines_eq(options
->AlternateHSAuthority
,
1057 old_options
->AlternateHSAuthority
);
1059 if (!need_to_update
)
1060 return 0; /* all done */
1062 /* Start from a clean slate. */
1063 clear_trusted_dir_servers();
1065 if (!options
->DirServers
) {
1066 /* then we may want some of the defaults */
1067 authority_type_t type
= NO_AUTHORITY
;
1068 if (!options
->AlternateBridgeAuthority
)
1069 type
|= BRIDGE_AUTHORITY
;
1070 if (!options
->AlternateDirAuthority
)
1071 type
|= V1_AUTHORITY
| V2_AUTHORITY
| V3_AUTHORITY
;
1072 if (!options
->AlternateHSAuthority
)
1073 type
|= HIDSERV_AUTHORITY
;
1074 add_default_trusted_dir_authorities(type
);
1077 for (cl
= options
->DirServers
; cl
; cl
= cl
->next
)
1078 if (parse_dir_server_line(cl
->value
, NO_AUTHORITY
, 0)<0)
1080 for (cl
= options
->AlternateBridgeAuthority
; cl
; cl
= cl
->next
)
1081 if (parse_dir_server_line(cl
->value
, NO_AUTHORITY
, 0)<0)
1083 for (cl
= options
->AlternateDirAuthority
; cl
; cl
= cl
->next
)
1084 if (parse_dir_server_line(cl
->value
, NO_AUTHORITY
, 0)<0)
1086 for (cl
= options
->AlternateHSAuthority
; cl
; cl
= cl
->next
)
1087 if (parse_dir_server_line(cl
->value
, NO_AUTHORITY
, 0)<0)
1092 /** Fetch the active option list, and take actions based on it. All of the
1093 * things we do should survive being done repeatedly. If present,
1094 * <b>old_options</b> contains the previous value of the options.
1096 * Return 0 if all goes well, return -1 if things went badly.
1099 options_act_reversible(or_options_t
*old_options
, char **msg
)
1101 smartlist_t
*new_listeners
= smartlist_create();
1102 smartlist_t
*replaced_listeners
= smartlist_create();
1103 static int libevent_initialized
= 0;
1104 or_options_t
*options
= get_options();
1105 int running_tor
= options
->command
== CMD_RUN_TOR
;
1106 int set_conn_limit
= 0;
1108 int logs_marked
= 0;
1110 /* Daemonize _first_, since we only want to open most of this stuff in
1111 * the subprocess. Libevent bases can't be reliably inherited across
1113 if (running_tor
&& options
->RunAsDaemon
) {
1114 /* No need to roll back, since you can't change the value. */
1118 #ifndef HAVE_SYS_UN_H
1119 if (options
->ControlSocket
) {
1120 *msg
= tor_strdup("Unix domain sockets (ControlSocket) not supported"
1121 " on this OS/with this build.");
1127 /* We need to set the connection limit before we can open the listeners. */
1128 if (set_max_file_descriptors((unsigned)options
->ConnLimit
,
1129 &options
->_ConnLimit
) < 0) {
1130 *msg
= tor_strdup("Problem with ConnLimit value. See logs for details.");
1135 /* Set up libevent. (We need to do this before we can register the
1136 * listeners as listeners.) */
1137 if (running_tor
&& !libevent_initialized
) {
1139 libevent_initialized
= 1;
1142 /* Launch the listeners. (We do this before we setuid, so we can bind to
1143 * ports under 1024.) */
1144 if (retry_all_listeners(replaced_listeners
, new_listeners
) < 0) {
1145 *msg
= tor_strdup("Failed to bind one of the listener ports.");
1150 #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
1151 /* Open /dev/pf before dropping privileges. */
1152 if (options
->TransPort
) {
1153 if (get_pf_socket() < 0) {
1154 *msg
= tor_strdup("Unable to open /dev/pf for transparent proxy.");
1160 /* Attempt to lock all current and future memory with mlockall() only once */
1161 if (options
->DisableAllSwap
) {
1162 if (tor_mlockall() == -1) {
1163 *msg
= tor_strdup("DisableAllSwap failure. Do you have proper "
1169 /* Setuid/setgid as appropriate */
1170 if (options
->User
) {
1171 if (switch_id(options
->User
) != 0) {
1172 /* No need to roll back, since you can't change the value. */
1173 *msg
= tor_strdup("Problem with User value. See logs for details.");
1178 /* Ensure data directory is private; create if possible. */
1179 if (check_private_dir(options
->DataDirectory
,
1180 running_tor
? CPD_CREATE
: CPD_CHECK
)<0) {
1182 int tmp
= tor_snprintf(buf
, sizeof(buf
),
1183 "Couldn't access/create private data directory \"%s\"",
1184 options
->DataDirectory
);
1185 *msg
= tor_strdup(tmp
>= 0 ? buf
: "internal error");
1187 /* No need to roll back, since you can't change the value. */
1190 if (directory_caches_v2_dir_info(options
)) {
1191 size_t len
= strlen(options
->DataDirectory
)+32;
1192 char *fn
= tor_malloc(len
);
1193 tor_snprintf(fn
, len
, "%s"PATH_SEPARATOR
"cached-status",
1194 options
->DataDirectory
);
1195 if (check_private_dir(fn
, running_tor
? CPD_CREATE
: CPD_CHECK
) < 0) {
1197 int tmp
= tor_snprintf(buf
, sizeof(buf
),
1198 "Couldn't access/create private data directory \"%s\"", fn
);
1199 *msg
= tor_strdup(tmp
>= 0 ? buf
: "internal error");
1206 /* Bail out at this point if we're not going to be a client or server:
1207 * we don't run Tor itself. */
1211 mark_logs_temp(); /* Close current logs once new logs are open. */
1213 if (options_init_logs(options
, 0)<0) { /* Configure the log(s) */
1214 *msg
= tor_strdup("Failed to init Log options. See logs for details.");
1221 log_severity_list_t
*severity
=
1222 tor_malloc_zero(sizeof(log_severity_list_t
));
1224 add_callback_log(severity
, control_event_logmsg
);
1225 control_adjust_event_log_severity();
1228 SMARTLIST_FOREACH(replaced_listeners
, connection_t
*, conn
,
1230 log_notice(LD_NET
, "Closing old %s on %s:%d",
1231 conn_type_to_string(conn
->type
), conn
->address
, conn
->port
);
1232 connection_close_immediate(conn
);
1233 connection_mark_for_close(conn
);
1242 rollback_log_changes();
1243 control_adjust_event_log_severity();
1246 if (set_conn_limit
&& old_options
)
1247 set_max_file_descriptors((unsigned)old_options
->ConnLimit
,
1248 &options
->_ConnLimit
);
1250 SMARTLIST_FOREACH(new_listeners
, connection_t
*, conn
,
1252 log_notice(LD_NET
, "Closing partially-constructed listener %s on %s:%d",
1253 conn_type_to_string(conn
->type
), conn
->address
, conn
->port
);
1254 connection_close_immediate(conn
);
1255 connection_mark_for_close(conn
);
1259 smartlist_free(new_listeners
);
1260 smartlist_free(replaced_listeners
);
1264 /** If we need to have a GEOIP ip-to-country map to run with our configured
1265 * options, return 1 and set *<b>reason_out</b> to a description of why. */
1267 options_need_geoip_info(or_options_t
*options
, const char **reason_out
)
1270 options
->BridgeRelay
&& options
->BridgeRecordUsageByCountry
;
1271 int routerset_usage
=
1272 routerset_needs_geoip(options
->EntryNodes
) ||
1273 routerset_needs_geoip(options
->ExitNodes
) ||
1274 routerset_needs_geoip(options
->ExcludeExitNodes
) ||
1275 routerset_needs_geoip(options
->ExcludeNodes
);
1277 if (routerset_usage
&& reason_out
) {
1278 *reason_out
= "We've been configured to use (or avoid) nodes in certain "
1279 "countries, and we need GEOIP information to figure out which ones they "
1281 } else if (bridge_usage
&& reason_out
) {
1282 *reason_out
= "We've been configured to see which countries can access "
1283 "us as a bridge, and we need GEOIP information to tell which countries "
1286 return bridge_usage
|| routerset_usage
;
1289 /** Return the bandwidthrate that we are going to report to the authorities
1290 * based on the config options. */
1292 get_effective_bwrate(or_options_t
*options
)
1294 uint64_t bw
= options
->BandwidthRate
;
1295 if (bw
> options
->MaxAdvertisedBandwidth
)
1296 bw
= options
->MaxAdvertisedBandwidth
;
1297 if (options
->RelayBandwidthRate
> 0 && bw
> options
->RelayBandwidthRate
)
1298 bw
= options
->RelayBandwidthRate
;
1299 /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
1300 return (uint32_t)bw
;
1303 /** Return the bandwidthburst that we are going to report to the authorities
1304 * based on the config options. */
1306 get_effective_bwburst(or_options_t
*options
)
1308 uint64_t bw
= options
->BandwidthBurst
;
1309 if (options
->RelayBandwidthBurst
> 0 && bw
> options
->RelayBandwidthBurst
)
1310 bw
= options
->RelayBandwidthBurst
;
1311 /* ensure_bandwidth_cap() makes sure that this cast can't overflow. */
1312 return (uint32_t)bw
;
1315 /** Fetch the active option list, and take actions based on it. All of the
1316 * things we do should survive being done repeatedly. If present,
1317 * <b>old_options</b> contains the previous value of the options.
1319 * Return 0 if all goes well, return -1 if it's time to die.
1321 * Note: We haven't moved all the "act on new configuration" logic
1322 * here yet. Some is still in do_hup() and other places.
1325 options_act(or_options_t
*old_options
)
1328 or_options_t
*options
= get_options();
1329 int running_tor
= options
->command
== CMD_RUN_TOR
;
1332 if (running_tor
&& !have_lockfile()) {
1333 if (try_locking(options
, 1) < 0)
1337 if (consider_adding_dir_authorities(options
, old_options
) < 0)
1340 if (options
->Bridges
) {
1341 clear_bridge_list();
1342 for (cl
= options
->Bridges
; cl
; cl
= cl
->next
) {
1343 if (parse_bridge_line(cl
->value
, 0)<0) {
1345 "Previously validated Bridge line could not be added!");
1351 if (running_tor
&& rend_config_services(options
, 0)<0) {
1353 "Previously validated hidden services line could not be added!");
1357 if (running_tor
&& rend_parse_service_authorization(options
, 0) < 0) {
1358 log_warn(LD_BUG
, "Previously validated client authorization for "
1359 "hidden services could not be added!");
1364 if (! global_state
&& running_tor
) {
1365 if (or_state_load())
1367 rep_hist_load_mtbf_data(time(NULL
));
1370 /* Bail out at this point if we're not going to be a client or server:
1371 * we want to not fork, and to log stuff to stderr. */
1375 /* Finish backgrounding the process */
1376 if (options
->RunAsDaemon
) {
1377 /* We may be calling this for the n'th time (on SIGHUP), but it's safe. */
1378 finish_daemon(options
->DataDirectory
);
1381 /* Write our PID to the PID file. If we do not have write permissions we
1382 * will log a warning */
1383 if (options
->PidFile
)
1384 write_pidfile(options
->PidFile
);
1386 /* Register addressmap directives */
1387 config_register_addressmaps(options
);
1388 parse_virtual_addr_network(options
->VirtualAddrNetwork
, 0, &msg
);
1390 /* Update address policies. */
1391 if (policies_parse_from_options(options
) < 0) {
1392 /* This should be impossible, but let's be sure. */
1393 log_warn(LD_BUG
,"Error parsing already-validated policy options.");
1397 if (init_cookie_authentication(options
->CookieAuthentication
) < 0) {
1398 log_warn(LD_CONFIG
,"Error creating cookie authentication file.");
1402 /* reload keys as needed for rendezvous services. */
1403 if (rend_service_load_keys()<0) {
1404 log_warn(LD_GENERAL
,"Error loading rendezvous service keys");
1408 /* Set up accounting */
1409 if (accounting_parse_options(options
, 0)<0) {
1410 log_warn(LD_CONFIG
,"Error in accounting options");
1413 if (accounting_is_enabled(options
))
1414 configure_accounting(time(NULL
));
1416 /* Change the cell EWMA settings */
1417 cell_ewma_set_scale_factor(options
, networkstatus_get_latest_consensus());
1419 /* Check for transitions that need action. */
1422 if ((options
->UseEntryGuards
&& !old_options
->UseEntryGuards
) ||
1423 (options
->ExcludeNodes
&&
1424 !routerset_equal(old_options
->ExcludeNodes
,options
->ExcludeNodes
)) ||
1425 (options
->ExcludeExitNodes
&&
1426 !routerset_equal(old_options
->ExcludeExitNodes
,
1427 options
->ExcludeExitNodes
))) {
1429 "Changed to using entry guards, or changed ExcludeNodes, or "
1430 "changed ExcludeExitNodes. Abandoning previous circuits.");
1431 circuit_mark_all_unused_circs();
1432 circuit_expire_all_dirty_circs();
1435 if (! bool_eq(options
->BridgeRelay
, old_options
->BridgeRelay
)) {
1436 log_info(LD_GENERAL
, "Bridge status changed. Forgetting GeoIP stats.");
1437 geoip_remove_old_clients(time(NULL
)+(2*60*60));
1440 if (options_transition_affects_workers(old_options
, options
)) {
1441 log_info(LD_GENERAL
,
1442 "Worker-related options changed. Rotating workers.");
1443 if (server_mode(options
) && !server_mode(old_options
)) {
1444 if (init_keys() < 0) {
1445 log_warn(LD_BUG
,"Error initializing keys; exiting");
1448 ip_address_changed(0);
1449 if (has_completed_circuit
|| !any_predicted_circuits(time(NULL
)))
1450 inform_testing_reachability();
1452 cpuworkers_rotate();
1460 if (options
->V3AuthoritativeDir
&& !old_options
->V3AuthoritativeDir
)
1464 /* Maybe load geoip file */
1465 if (options
->GeoIPFile
&&
1466 ((!old_options
|| !opt_streq(old_options
->GeoIPFile
, options
->GeoIPFile
))
1467 || !geoip_is_loaded())) {
1468 /* XXXX Don't use this "<default>" junk; make our filename options
1469 * understand prefixes somehow. -NM */
1470 /* XXXX021 Reload GeoIPFile on SIGHUP. -NM */
1471 char *actual_fname
= tor_strdup(options
->GeoIPFile
);
1473 if (!strcmp(actual_fname
, "<default>")) {
1474 const char *conf_root
= get_windows_conf_root();
1475 size_t len
= strlen(conf_root
)+16;
1476 tor_free(actual_fname
);
1477 actual_fname
= tor_malloc(len
+1);
1478 tor_snprintf(actual_fname
, len
, "%s\\geoip", conf_root
);
1481 geoip_load_file(actual_fname
, options
);
1482 tor_free(actual_fname
);
1485 if (options
->DirReqStatistics
&& !geoip_is_loaded()) {
1486 /* Check if GeoIP database could be loaded. */
1487 log_warn(LD_CONFIG
, "Configured to measure directory request "
1488 "statistics, but no GeoIP database found!");
1492 if (options
->EntryStatistics
) {
1493 if (should_record_bridge_info(options
)) {
1494 /* Don't allow measuring statistics on entry guards when configured
1496 log_warn(LD_CONFIG
, "Bridges cannot be configured to measure "
1497 "additional GeoIP statistics as entry guards.");
1499 } else if (!geoip_is_loaded()) {
1500 /* Check if GeoIP database could be loaded. */
1501 log_warn(LD_CONFIG
, "Configured to measure entry node statistics, "
1502 "but no GeoIP database found!");
1507 /* Check if we need to parse and add the EntryNodes config option. */
1508 if (options
->EntryNodes
&&
1510 (!routerset_equal(old_options
->EntryNodes
,options
->EntryNodes
))))
1511 entry_nodes_should_be_added();
1513 /* Since our options changed, we might need to regenerate and upload our
1514 * server descriptor.
1517 options_transition_affects_descriptor(old_options
, options
))
1518 mark_my_descriptor_dirty();
1520 /* We may need to reschedule some directory stuff if our status changed. */
1522 if (authdir_mode_v3(options
) && !authdir_mode_v3(old_options
))
1523 dirvote_recalculate_timing(options
, time(NULL
));
1524 if (!bool_eq(directory_fetches_dir_info_early(options
),
1525 directory_fetches_dir_info_early(old_options
)) ||
1526 !bool_eq(directory_fetches_dir_info_later(options
),
1527 directory_fetches_dir_info_later(old_options
))) {
1528 /* Make sure update_router_have_min_dir_info gets called. */
1529 router_dir_info_changed();
1530 /* We might need to download a new consensus status later or sooner than
1531 * we had expected. */
1532 update_consensus_networkstatus_fetch_time(time(NULL
));
1536 /* Load the webpage we're going to serve every time someone asks for '/' on
1538 tor_free(global_dirfrontpagecontents
);
1539 if (options
->DirPortFrontPage
) {
1540 global_dirfrontpagecontents
=
1541 read_file_to_str(options
->DirPortFrontPage
, 0, NULL
);
1542 if (!global_dirfrontpagecontents
) {
1544 "DirPortFrontPage file '%s' not found. Continuing anyway.",
1545 options
->DirPortFrontPage
);
1553 * Functions to parse config options
1556 /** If <b>option</b> is an official abbreviation for a longer option,
1557 * return the longer option. Otherwise return <b>option</b>.
1558 * If <b>command_line</b> is set, apply all abbreviations. Otherwise, only
1559 * apply abbreviations that work for the config file and the command line.
1560 * If <b>warn_obsolete</b> is set, warn about deprecated names. */
1562 expand_abbrev(config_format_t
*fmt
, const char *option
, int command_line
,
1568 for (i
=0; fmt
->abbrevs
[i
].abbreviated
; ++i
) {
1569 /* Abbreviations are case insensitive. */
1570 if (!strcasecmp(option
,fmt
->abbrevs
[i
].abbreviated
) &&
1571 (command_line
|| !fmt
->abbrevs
[i
].commandline_only
)) {
1572 if (warn_obsolete
&& fmt
->abbrevs
[i
].warn
) {
1574 "The configuration option '%s' is deprecated; "
1575 "use '%s' instead.",
1576 fmt
->abbrevs
[i
].abbreviated
,
1577 fmt
->abbrevs
[i
].full
);
1579 /* Keep going through the list in case we want to rewrite it more.
1580 * (We could imagine recursing here, but I don't want to get the
1581 * user into an infinite loop if we craft our list wrong.) */
1582 option
= fmt
->abbrevs
[i
].full
;
1588 /** Helper: Read a list of configuration options from the command line.
1589 * If successful, put them in *<b>result</b> and return 0, and return
1590 * -1 and leave *<b>result</b> alone. */
1592 config_get_commandlines(int argc
, char **argv
, config_line_t
**result
)
1594 config_line_t
*front
= NULL
;
1595 config_line_t
**new = &front
;
1600 if (!strcmp(argv
[i
],"-f") ||
1601 !strcmp(argv
[i
],"--hash-password")) {
1602 i
+= 2; /* command-line option with argument. ignore them. */
1604 } else if (!strcmp(argv
[i
],"--list-fingerprint") ||
1605 !strcmp(argv
[i
],"--verify-config") ||
1606 !strcmp(argv
[i
],"--ignore-missing-torrc") ||
1607 !strcmp(argv
[i
],"--quiet") ||
1608 !strcmp(argv
[i
],"--hush")) {
1609 i
+= 1; /* command-line option. ignore it. */
1611 } else if (!strcmp(argv
[i
],"--nt-service") ||
1612 !strcmp(argv
[i
],"-nt-service")) {
1618 log_warn(LD_CONFIG
,"Command-line option '%s' with no value. Failing.",
1620 config_free_lines(front
);
1624 *new = tor_malloc_zero(sizeof(config_line_t
));
1627 /* Each keyword may be prefixed with one or two dashes. */
1633 (*new)->key
= tor_strdup(expand_abbrev(&options_format
, s
, 1, 1));
1634 (*new)->value
= tor_strdup(argv
[i
+1]);
1635 (*new)->next
= NULL
;
1636 log(LOG_DEBUG
, LD_CONFIG
, "command line: parsed keyword '%s', value '%s'",
1637 (*new)->key
, (*new)->value
);
1639 new = &((*new)->next
);
1646 /** Helper: allocate a new configuration option mapping 'key' to 'val',
1647 * append it to *<b>lst</b>. */
1649 config_line_append(config_line_t
**lst
,
1653 config_line_t
*newline
;
1655 newline
= tor_malloc(sizeof(config_line_t
));
1656 newline
->key
= tor_strdup(key
);
1657 newline
->value
= tor_strdup(val
);
1658 newline
->next
= NULL
;
1660 lst
= &((*lst
)->next
);
1665 /** Helper: parse the config string and strdup into key/value
1666 * strings. Set *result to the list, or NULL if parsing the string
1667 * failed. Return 0 on success, -1 on failure. Warn and ignore any
1668 * misformatted lines. */
1670 config_get_lines(const char *string
, config_line_t
**result
)
1672 config_line_t
*list
= NULL
, **next
;
1678 string
= parse_config_line_from_str(string
, &k
, &v
);
1680 config_free_lines(list
);
1686 /* This list can get long, so we keep a pointer to the end of it
1687 * rather than using config_line_append over and over and getting
1688 * n^2 performance. */
1689 *next
= tor_malloc(sizeof(config_line_t
));
1692 (*next
)->next
= NULL
;
1693 next
= &((*next
)->next
);
1705 * Free all the configuration lines on the linked list <b>front</b>.
1708 config_free_lines(config_line_t
*front
)
1717 tor_free(tmp
->value
);
1722 /** Return the description for a given configuration variable, or NULL if no
1723 * description exists. */
1725 config_find_description(config_format_t
*fmt
, const char *name
)
1728 for (i
=0; fmt
->descriptions
[i
].name
; ++i
) {
1729 if (!strcasecmp(name
, fmt
->descriptions
[i
].name
))
1730 return fmt
->descriptions
[i
].description
;
1735 /** If <b>key</b> is a configuration option, return the corresponding
1736 * config_var_t. Otherwise, if <b>key</b> is a non-standard abbreviation,
1737 * warn, and return the corresponding config_var_t. Otherwise return NULL.
1739 static config_var_t
*
1740 config_find_option(config_format_t
*fmt
, const char *key
)
1743 size_t keylen
= strlen(key
);
1745 return NULL
; /* if they say "--" on the command line, it's not an option */
1746 /* First, check for an exact (case-insensitive) match */
1747 for (i
=0; fmt
->vars
[i
].name
; ++i
) {
1748 if (!strcasecmp(key
, fmt
->vars
[i
].name
)) {
1749 return &fmt
->vars
[i
];
1752 /* If none, check for an abbreviated match */
1753 for (i
=0; fmt
->vars
[i
].name
; ++i
) {
1754 if (!strncasecmp(key
, fmt
->vars
[i
].name
, keylen
)) {
1755 log_warn(LD_CONFIG
, "The abbreviation '%s' is deprecated. "
1756 "Please use '%s' instead",
1757 key
, fmt
->vars
[i
].name
);
1758 return &fmt
->vars
[i
];
1761 /* Okay, unrecognized option */
1766 * Functions to assign config options.
1769 /** <b>c</b>-\>key is known to be a real key. Update <b>options</b>
1770 * with <b>c</b>-\>value and return 0, or return -1 if bad value.
1772 * Called from config_assign_line() and option_reset().
1775 config_assign_value(config_format_t
*fmt
, or_options_t
*options
,
1776 config_line_t
*c
, char **msg
)
1783 CHECK(fmt
, options
);
1785 var
= config_find_option(fmt
, c
->key
);
1788 lvalue
= STRUCT_VAR_P(options
, var
->var_offset
);
1790 switch (var
->type
) {
1792 case CONFIG_TYPE_UINT
:
1793 i
= (int)tor_parse_long(c
->value
, 10, 0, INT_MAX
, &ok
, NULL
);
1795 r
= tor_snprintf(buf
, sizeof(buf
),
1796 "Int keyword '%s %s' is malformed or out of bounds.",
1798 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
1804 case CONFIG_TYPE_INTERVAL
: {
1805 i
= config_parse_interval(c
->value
, &ok
);
1807 r
= tor_snprintf(buf
, sizeof(buf
),
1808 "Interval '%s %s' is malformed or out of bounds.",
1810 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
1817 case CONFIG_TYPE_MEMUNIT
: {
1818 uint64_t u64
= config_parse_memunit(c
->value
, &ok
);
1820 r
= tor_snprintf(buf
, sizeof(buf
),
1821 "Value '%s %s' is malformed or out of bounds.",
1823 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
1826 *(uint64_t *)lvalue
= u64
;
1830 case CONFIG_TYPE_BOOL
:
1831 i
= (int)tor_parse_long(c
->value
, 10, 0, 1, &ok
, NULL
);
1833 r
= tor_snprintf(buf
, sizeof(buf
),
1834 "Boolean '%s %s' expects 0 or 1.",
1836 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
1842 case CONFIG_TYPE_STRING
:
1843 case CONFIG_TYPE_FILENAME
:
1844 tor_free(*(char **)lvalue
);
1845 *(char **)lvalue
= tor_strdup(c
->value
);
1848 case CONFIG_TYPE_DOUBLE
:
1849 *(double *)lvalue
= atof(c
->value
);
1852 case CONFIG_TYPE_ISOTIME
:
1853 if (parse_iso_time(c
->value
, (time_t *)lvalue
)) {
1854 r
= tor_snprintf(buf
, sizeof(buf
),
1855 "Invalid time '%s' for keyword '%s'", c
->value
, c
->key
);
1856 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
1861 case CONFIG_TYPE_ROUTERSET
:
1862 if (*(routerset_t
**)lvalue
) {
1863 routerset_free(*(routerset_t
**)lvalue
);
1865 *(routerset_t
**)lvalue
= routerset_new();
1866 if (routerset_parse(*(routerset_t
**)lvalue
, c
->value
, c
->key
)<0) {
1867 tor_snprintf(buf
, sizeof(buf
), "Invalid exit list '%s' for option '%s'",
1869 *msg
= tor_strdup(buf
);
1874 case CONFIG_TYPE_CSV
:
1875 if (*(smartlist_t
**)lvalue
) {
1876 SMARTLIST_FOREACH(*(smartlist_t
**)lvalue
, char *, cp
, tor_free(cp
));
1877 smartlist_clear(*(smartlist_t
**)lvalue
);
1879 *(smartlist_t
**)lvalue
= smartlist_create();
1882 smartlist_split_string(*(smartlist_t
**)lvalue
, c
->value
, ",",
1883 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 0);
1886 case CONFIG_TYPE_LINELIST
:
1887 case CONFIG_TYPE_LINELIST_S
:
1888 config_line_append((config_line_t
**)lvalue
, c
->key
, c
->value
);
1890 case CONFIG_TYPE_OBSOLETE
:
1891 log_warn(LD_CONFIG
, "Skipping obsolete configuration option '%s'", c
->key
);
1893 case CONFIG_TYPE_LINELIST_V
:
1894 r
= tor_snprintf(buf
, sizeof(buf
),
1895 "You may not provide a value for virtual option '%s'", c
->key
);
1896 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
1905 /** If <b>c</b> is a syntactically valid configuration line, update
1906 * <b>options</b> with its value and return 0. Otherwise return -1 for bad
1907 * key, -2 for bad value.
1909 * If <b>clear_first</b> is set, clear the value first. Then if
1910 * <b>use_defaults</b> is set, set the value to the default.
1912 * Called from config_assign().
1915 config_assign_line(config_format_t
*fmt
, or_options_t
*options
,
1916 config_line_t
*c
, int use_defaults
,
1917 int clear_first
, char **msg
)
1921 CHECK(fmt
, options
);
1923 var
= config_find_option(fmt
, c
->key
);
1926 void *lvalue
= STRUCT_VAR_P(options
, fmt
->extra
->var_offset
);
1928 "Found unrecognized option '%s'; saving it.", c
->key
);
1929 config_line_append((config_line_t
**)lvalue
, c
->key
, c
->value
);
1933 int tmp
= tor_snprintf(buf
, sizeof(buf
),
1934 "Unknown option '%s'. Failing.", c
->key
);
1935 *msg
= tor_strdup(tmp
>= 0 ? buf
: "internal error");
1939 /* Put keyword into canonical case. */
1940 if (strcmp(var
->name
, c
->key
)) {
1942 c
->key
= tor_strdup(var
->name
);
1945 if (!strlen(c
->value
)) {
1946 /* reset or clear it, then return */
1948 if (var
->type
== CONFIG_TYPE_LINELIST
||
1949 var
->type
== CONFIG_TYPE_LINELIST_S
) {
1950 /* We got an empty linelist from the torrc or command line.
1951 As a special case, call this an error. Warn and ignore. */
1953 "Linelist option '%s' has no value. Skipping.", c
->key
);
1954 } else { /* not already cleared */
1955 option_reset(fmt
, options
, var
, use_defaults
);
1961 if (config_assign_value(fmt
, options
, c
, msg
) < 0)
1966 /** Restore the option named <b>key</b> in options to its default value.
1967 * Called from config_assign(). */
1969 config_reset_line(config_format_t
*fmt
, or_options_t
*options
,
1970 const char *key
, int use_defaults
)
1974 CHECK(fmt
, options
);
1976 var
= config_find_option(fmt
, key
);
1978 return; /* give error on next pass. */
1980 option_reset(fmt
, options
, var
, use_defaults
);
1983 /** Return true iff key is a valid configuration option. */
1985 option_is_recognized(const char *key
)
1987 config_var_t
*var
= config_find_option(&options_format
, key
);
1988 return (var
!= NULL
);
1991 /** Return the canonical name of a configuration option, or NULL
1992 * if no such option exists. */
1994 option_get_canonical_name(const char *key
)
1996 config_var_t
*var
= config_find_option(&options_format
, key
);
1997 return var
? var
->name
: NULL
;
2000 /** Return a canonical list of the options assigned for key.
2003 option_get_assignment(or_options_t
*options
, const char *key
)
2005 return get_assigned_option(&options_format
, options
, key
, 1);
2008 /** Return true iff value needs to be quoted and escaped to be used in
2009 * a configuration file. */
2011 config_value_needs_escape(const char *value
)
2021 /* Note: quotes and backspaces need special handling when we are using
2022 * quotes, not otherwise, so they don't trigger escaping on their
2026 if (!TOR_ISPRINT(*value
))
2034 /** Return a newly allocated deep copy of the lines in <b>inp</b>. */
2035 static config_line_t
*
2036 config_lines_dup(const config_line_t
*inp
)
2038 config_line_t
*result
= NULL
;
2039 config_line_t
**next_out
= &result
;
2041 *next_out
= tor_malloc(sizeof(config_line_t
));
2042 (*next_out
)->key
= tor_strdup(inp
->key
);
2043 (*next_out
)->value
= tor_strdup(inp
->value
);
2045 next_out
= &((*next_out
)->next
);
2051 /** Return newly allocated line or lines corresponding to <b>key</b> in the
2052 * configuration <b>options</b>. If <b>escape_val</b> is true and a
2053 * value needs to be quoted before it's put in a config file, quote and
2054 * escape that value. Return NULL if no such key exists. */
2055 static config_line_t
*
2056 get_assigned_option(config_format_t
*fmt
, void *options
,
2057 const char *key
, int escape_val
)
2062 config_line_t
*result
;
2063 tor_assert(options
&& key
);
2065 CHECK(fmt
, options
);
2067 var
= config_find_option(fmt
, key
);
2069 log_warn(LD_CONFIG
, "Unknown option '%s'. Failing.", key
);
2072 value
= STRUCT_VAR_P(options
, var
->var_offset
);
2074 result
= tor_malloc_zero(sizeof(config_line_t
));
2075 result
->key
= tor_strdup(var
->name
);
2078 case CONFIG_TYPE_STRING
:
2079 case CONFIG_TYPE_FILENAME
:
2080 if (*(char**)value
) {
2081 result
->value
= tor_strdup(*(char**)value
);
2083 tor_free(result
->key
);
2088 case CONFIG_TYPE_ISOTIME
:
2089 if (*(time_t*)value
) {
2090 result
->value
= tor_malloc(ISO_TIME_LEN
+1);
2091 format_iso_time(result
->value
, *(time_t*)value
);
2093 tor_free(result
->key
);
2096 escape_val
= 0; /* Can't need escape. */
2098 case CONFIG_TYPE_INTERVAL
:
2099 case CONFIG_TYPE_UINT
:
2100 /* This means every or_options_t uint or bool element
2101 * needs to be an int. Not, say, a uint16_t or char. */
2102 tor_snprintf(buf
, sizeof(buf
), "%d", *(int*)value
);
2103 result
->value
= tor_strdup(buf
);
2104 escape_val
= 0; /* Can't need escape. */
2106 case CONFIG_TYPE_MEMUNIT
:
2107 tor_snprintf(buf
, sizeof(buf
), U64_FORMAT
,
2108 U64_PRINTF_ARG(*(uint64_t*)value
));
2109 result
->value
= tor_strdup(buf
);
2110 escape_val
= 0; /* Can't need escape. */
2112 case CONFIG_TYPE_DOUBLE
:
2113 tor_snprintf(buf
, sizeof(buf
), "%f", *(double*)value
);
2114 result
->value
= tor_strdup(buf
);
2115 escape_val
= 0; /* Can't need escape. */
2117 case CONFIG_TYPE_BOOL
:
2118 result
->value
= tor_strdup(*(int*)value
? "1" : "0");
2119 escape_val
= 0; /* Can't need escape. */
2121 case CONFIG_TYPE_ROUTERSET
:
2122 result
->value
= routerset_to_string(*(routerset_t
**)value
);
2124 case CONFIG_TYPE_CSV
:
2125 if (*(smartlist_t
**)value
)
2127 smartlist_join_strings(*(smartlist_t
**)value
, ",", 0, NULL
);
2129 result
->value
= tor_strdup("");
2131 case CONFIG_TYPE_OBSOLETE
:
2132 log_fn(LOG_PROTOCOL_WARN
, LD_CONFIG
,
2133 "You asked me for the value of an obsolete config option '%s'.",
2135 tor_free(result
->key
);
2138 case CONFIG_TYPE_LINELIST_S
:
2140 "Can't return context-sensitive '%s' on its own", key
);
2141 tor_free(result
->key
);
2144 case CONFIG_TYPE_LINELIST
:
2145 case CONFIG_TYPE_LINELIST_V
:
2146 tor_free(result
->key
);
2148 result
= config_lines_dup(*(const config_line_t
**)value
);
2151 tor_free(result
->key
);
2153 log_warn(LD_BUG
,"Unknown type %d for known key '%s'",
2159 config_line_t
*line
;
2160 for (line
= result
; line
; line
= line
->next
) {
2161 if (line
->value
&& config_value_needs_escape(line
->value
)) {
2162 char *newval
= esc_for_log(line
->value
);
2163 tor_free(line
->value
);
2164 line
->value
= newval
;
2172 /** Iterate through the linked list of requested options <b>list</b>.
2173 * For each item, convert as appropriate and assign to <b>options</b>.
2174 * If an item is unrecognized, set *msg and return -1 immediately,
2175 * else return 0 for success.
2177 * If <b>clear_first</b>, interpret config options as replacing (not
2178 * extending) their previous values. If <b>clear_first</b> is set,
2179 * then <b>use_defaults</b> to decide if you set to defaults after
2180 * clearing, or make the value 0 or NULL.
2182 * Here are the use cases:
2183 * 1. A non-empty AllowInvalid line in your torrc. Appends to current
2184 * if linelist, replaces current if csv.
2185 * 2. An empty AllowInvalid line in your torrc. Should clear it.
2186 * 3. "RESETCONF AllowInvalid" sets it to default.
2187 * 4. "SETCONF AllowInvalid" makes it NULL.
2188 * 5. "SETCONF AllowInvalid=foo" clears it and sets it to "foo".
2190 * Use_defaults Clear_first
2192 * 1 0 undefined, don't use
2193 * 0 1 "set to null first"
2194 * 1 1 "set to defaults first"
2195 * Return 0 on success, -1 on bad key, -2 on bad value.
2197 * As an additional special case, if a LINELIST config option has
2198 * no value and clear_first is 0, then warn and ignore it.
2202 There are three call cases for config_assign() currently.
2204 Case one: Torrc entry
2205 options_init_from_torrc() calls config_assign(0, 0)
2206 calls config_assign_line(0, 0).
2207 if value is empty, calls option_reset(0) and returns.
2208 calls config_assign_value(), appends.
2211 options_trial_assign() calls config_assign(0, 1)
2212 calls config_reset_line(0)
2213 calls option_reset(0)
2214 calls option_clear().
2215 calls config_assign_line(0, 1).
2216 if value is empty, returns.
2217 calls config_assign_value(), appends.
2219 Case three: resetconf
2220 options_trial_assign() calls config_assign(1, 1)
2221 calls config_reset_line(1)
2222 calls option_reset(1)
2223 calls option_clear().
2224 calls config_assign_value(default)
2225 calls config_assign_line(1, 1).
2229 config_assign(config_format_t
*fmt
, void *options
, config_line_t
*list
,
2230 int use_defaults
, int clear_first
, char **msg
)
2234 CHECK(fmt
, options
);
2236 /* pass 1: normalize keys */
2237 for (p
= list
; p
; p
= p
->next
) {
2238 const char *full
= expand_abbrev(fmt
, p
->key
, 0, 1);
2239 if (strcmp(full
,p
->key
)) {
2241 p
->key
= tor_strdup(full
);
2245 /* pass 2: if we're reading from a resetting source, clear all
2246 * mentioned config options, and maybe set to their defaults. */
2248 for (p
= list
; p
; p
= p
->next
)
2249 config_reset_line(fmt
, options
, p
->key
, use_defaults
);
2252 /* pass 3: assign. */
2255 if ((r
=config_assign_line(fmt
, options
, list
, use_defaults
,
2263 /** Try assigning <b>list</b> to the global options. You do this by duping
2264 * options, assigning list to the new one, then validating it. If it's
2265 * ok, then throw out the old one and stick with the new one. Else,
2266 * revert to old and return failure. Return SETOPT_OK on success, or
2267 * a setopt_err_t on failure.
2269 * If not success, point *<b>msg</b> to a newly allocated string describing
2273 options_trial_assign(config_line_t
*list
, int use_defaults
,
2274 int clear_first
, char **msg
)
2277 or_options_t
*trial_options
= options_dup(&options_format
, get_options());
2279 if ((r
=config_assign(&options_format
, trial_options
,
2280 list
, use_defaults
, clear_first
, msg
)) < 0) {
2281 config_free(&options_format
, trial_options
);
2285 if (options_validate(get_options(), trial_options
, 1, msg
) < 0) {
2286 config_free(&options_format
, trial_options
);
2287 return SETOPT_ERR_PARSE
; /*XXX make this a separate return value. */
2290 if (options_transition_allowed(get_options(), trial_options
, msg
) < 0) {
2291 config_free(&options_format
, trial_options
);
2292 return SETOPT_ERR_TRANSITION
;
2295 if (set_options(trial_options
, msg
)<0) {
2296 config_free(&options_format
, trial_options
);
2297 return SETOPT_ERR_SETTING
;
2300 /* we liked it. put it in place. */
2304 /** Reset config option <b>var</b> to 0, 0.0, NULL, or the equivalent.
2305 * Called from option_reset() and config_free(). */
2307 option_clear(config_format_t
*fmt
, or_options_t
*options
, config_var_t
*var
)
2309 void *lvalue
= STRUCT_VAR_P(options
, var
->var_offset
);
2310 (void)fmt
; /* unused */
2311 switch (var
->type
) {
2312 case CONFIG_TYPE_STRING
:
2313 case CONFIG_TYPE_FILENAME
:
2314 tor_free(*(char**)lvalue
);
2316 case CONFIG_TYPE_DOUBLE
:
2317 *(double*)lvalue
= 0.0;
2319 case CONFIG_TYPE_ISOTIME
:
2320 *(time_t*)lvalue
= 0;
2322 case CONFIG_TYPE_INTERVAL
:
2323 case CONFIG_TYPE_UINT
:
2324 case CONFIG_TYPE_BOOL
:
2327 case CONFIG_TYPE_MEMUNIT
:
2328 *(uint64_t*)lvalue
= 0;
2330 case CONFIG_TYPE_ROUTERSET
:
2331 if (*(routerset_t
**)lvalue
) {
2332 routerset_free(*(routerset_t
**)lvalue
);
2333 *(routerset_t
**)lvalue
= NULL
;
2336 case CONFIG_TYPE_CSV
:
2337 if (*(smartlist_t
**)lvalue
) {
2338 SMARTLIST_FOREACH(*(smartlist_t
**)lvalue
, char *, cp
, tor_free(cp
));
2339 smartlist_free(*(smartlist_t
**)lvalue
);
2340 *(smartlist_t
**)lvalue
= NULL
;
2343 case CONFIG_TYPE_LINELIST
:
2344 case CONFIG_TYPE_LINELIST_S
:
2345 config_free_lines(*(config_line_t
**)lvalue
);
2346 *(config_line_t
**)lvalue
= NULL
;
2348 case CONFIG_TYPE_LINELIST_V
:
2349 /* handled by linelist_s. */
2351 case CONFIG_TYPE_OBSOLETE
:
2356 /** Clear the option indexed by <b>var</b> in <b>options</b>. Then if
2357 * <b>use_defaults</b>, set it to its default value.
2358 * Called by config_init() and option_reset_line() and option_assign_line(). */
2360 option_reset(config_format_t
*fmt
, or_options_t
*options
,
2361 config_var_t
*var
, int use_defaults
)
2365 CHECK(fmt
, options
);
2366 option_clear(fmt
, options
, var
); /* clear it first */
2368 return; /* all done */
2369 if (var
->initvalue
) {
2370 c
= tor_malloc_zero(sizeof(config_line_t
));
2371 c
->key
= tor_strdup(var
->name
);
2372 c
->value
= tor_strdup(var
->initvalue
);
2373 if (config_assign_value(fmt
, options
, c
, &msg
) < 0) {
2374 log_warn(LD_BUG
, "Failed to assign default: %s", msg
);
2375 tor_free(msg
); /* if this happens it's a bug */
2377 config_free_lines(c
);
2381 /** Print a usage message for tor. */
2386 "Copyright (c) 2001-2004, Roger Dingledine\n"
2387 "Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson\n"
2388 "Copyright (c) 2007-2009, The Tor Project, Inc.\n\n"
2389 "tor -f <torrc> [args]\n"
2390 "See man page for options, or https://www.torproject.org/ for "
2391 "documentation.\n");
2394 /** Print all non-obsolete torrc options. */
2396 list_torrc_options(void)
2399 smartlist_t
*lines
= smartlist_create();
2400 for (i
= 0; _option_vars
[i
].name
; ++i
) {
2401 config_var_t
*var
= &_option_vars
[i
];
2403 if (var
->type
== CONFIG_TYPE_OBSOLETE
||
2404 var
->type
== CONFIG_TYPE_LINELIST_V
)
2406 desc
= config_find_description(&options_format
, var
->name
);
2407 printf("%s\n", var
->name
);
2409 wrap_string(lines
, desc
, 76, " ", " ");
2410 SMARTLIST_FOREACH(lines
, char *, cp
, {
2414 smartlist_clear(lines
);
2417 smartlist_free(lines
);
2420 /** Last value actually set by resolve_my_address. */
2421 static uint32_t last_resolved_addr
= 0;
2423 * Based on <b>options-\>Address</b>, guess our public IP address and put it
2424 * (in host order) into *<b>addr_out</b>. If <b>hostname_out</b> is provided,
2425 * set *<b>hostname_out</b> to a new string holding the hostname we used to
2426 * get the address. Return 0 if all is well, or -1 if we can't find a suitable
2427 * public IP address.
2430 resolve_my_address(int warn_severity
, or_options_t
*options
,
2431 uint32_t *addr_out
, char **hostname_out
)
2434 struct hostent
*rent
;
2437 int explicit_hostname
=1;
2438 int from_interface
=0;
2439 char tmpbuf
[INET_NTOA_BUF_LEN
];
2440 const char *address
= options
->Address
;
2441 int notice_severity
= warn_severity
<= LOG_NOTICE
?
2442 LOG_NOTICE
: warn_severity
;
2444 tor_assert(addr_out
);
2446 if (address
&& *address
) {
2447 strlcpy(hostname
, address
, sizeof(hostname
));
2448 } else { /* then we need to guess our address */
2449 explicit_ip
= 0; /* it's implicit */
2450 explicit_hostname
= 0; /* it's implicit */
2452 if (gethostname(hostname
, sizeof(hostname
)) < 0) {
2453 log_fn(warn_severity
, LD_NET
,"Error obtaining local hostname");
2456 log_debug(LD_CONFIG
,"Guessed local host name as '%s'",hostname
);
2459 /* now we know hostname. resolve it and keep only the IP address */
2461 if (tor_inet_aton(hostname
, &in
) == 0) {
2462 /* then we have to resolve it */
2464 rent
= (struct hostent
*)gethostbyname(hostname
);
2466 uint32_t interface_ip
;
2468 if (explicit_hostname
) {
2469 log_fn(warn_severity
, LD_CONFIG
,
2470 "Could not resolve local Address '%s'. Failing.", hostname
);
2473 log_fn(notice_severity
, LD_CONFIG
,
2474 "Could not resolve guessed local hostname '%s'. "
2475 "Trying something else.", hostname
);
2476 if (get_interface_address(warn_severity
, &interface_ip
)) {
2477 log_fn(warn_severity
, LD_CONFIG
,
2478 "Could not get local interface IP address. Failing.");
2482 in
.s_addr
= htonl(interface_ip
);
2483 tor_inet_ntoa(&in
,tmpbuf
,sizeof(tmpbuf
));
2484 log_fn(notice_severity
, LD_CONFIG
, "Learned IP address '%s' for "
2485 "local interface. Using that.", tmpbuf
);
2486 strlcpy(hostname
, "<guessed from interfaces>", sizeof(hostname
));
2488 tor_assert(rent
->h_length
== 4);
2489 memcpy(&in
.s_addr
, rent
->h_addr
, rent
->h_length
);
2491 if (!explicit_hostname
&&
2492 is_internal_IP(ntohl(in
.s_addr
), 0)) {
2493 uint32_t interface_ip
;
2495 tor_inet_ntoa(&in
,tmpbuf
,sizeof(tmpbuf
));
2496 log_fn(notice_severity
, LD_CONFIG
, "Guessed local hostname '%s' "
2497 "resolves to a private IP address (%s). Trying something "
2498 "else.", hostname
, tmpbuf
);
2500 if (get_interface_address(warn_severity
, &interface_ip
)) {
2501 log_fn(warn_severity
, LD_CONFIG
,
2502 "Could not get local interface IP address. Too bad.");
2503 } else if (is_internal_IP(interface_ip
, 0)) {
2505 in2
.s_addr
= htonl(interface_ip
);
2506 tor_inet_ntoa(&in2
,tmpbuf
,sizeof(tmpbuf
));
2507 log_fn(notice_severity
, LD_CONFIG
,
2508 "Interface IP address '%s' is a private address too. "
2509 "Ignoring.", tmpbuf
);
2512 in
.s_addr
= htonl(interface_ip
);
2513 tor_inet_ntoa(&in
,tmpbuf
,sizeof(tmpbuf
));
2514 log_fn(notice_severity
, LD_CONFIG
,
2515 "Learned IP address '%s' for local interface."
2516 " Using that.", tmpbuf
);
2517 strlcpy(hostname
, "<guessed from interfaces>", sizeof(hostname
));
2523 tor_inet_ntoa(&in
,tmpbuf
,sizeof(tmpbuf
));
2524 if (is_internal_IP(ntohl(in
.s_addr
), 0) &&
2525 options
->_PublishServerDescriptor
) {
2526 /* make sure we're ok with publishing an internal IP */
2527 if (!options
->DirServers
&& !options
->AlternateDirAuthority
) {
2528 /* if they are using the default dirservers, disallow internal IPs
2530 log_fn(warn_severity
, LD_CONFIG
,
2531 "Address '%s' resolves to private IP address '%s'. "
2532 "Tor servers that use the default DirServers must have public "
2533 "IP addresses.", hostname
, tmpbuf
);
2537 /* even if they've set their own dirservers, require an explicit IP if
2538 * they're using an internal address. */
2539 log_fn(warn_severity
, LD_CONFIG
, "Address '%s' resolves to private "
2540 "IP address '%s'. Please set the Address config option to be "
2541 "the IP address you want to use.", hostname
, tmpbuf
);
2546 log_debug(LD_CONFIG
, "Resolved Address to '%s'.", tmpbuf
);
2547 *addr_out
= ntohl(in
.s_addr
);
2548 if (last_resolved_addr
&& last_resolved_addr
!= *addr_out
) {
2549 /* Leave this as a notice, regardless of the requested severity,
2550 * at least until dynamic IP address support becomes bulletproof. */
2552 "Your IP address seems to have changed to %s. Updating.",
2554 ip_address_changed(0);
2556 if (last_resolved_addr
!= *addr_out
) {
2558 const char *h
= hostname
;
2560 method
= "CONFIGURED";
2562 } else if (explicit_hostname
) {
2563 method
= "RESOLVED";
2564 } else if (from_interface
) {
2565 method
= "INTERFACE";
2568 method
= "GETHOSTNAME";
2570 control_event_server_status(LOG_NOTICE
,
2571 "EXTERNAL_ADDRESS ADDRESS=%s METHOD=%s %s%s",
2572 tmpbuf
, method
, h
?"HOSTNAME=":"", h
);
2574 last_resolved_addr
= *addr_out
;
2576 *hostname_out
= tor_strdup(hostname
);
2580 /** Return true iff <b>addr</b> is judged to be on the same network as us, or
2581 * on a private network.
2584 is_local_addr(const tor_addr_t
*addr
)
2586 if (tor_addr_is_internal(addr
, 0))
2588 /* Check whether ip is on the same /24 as we are. */
2589 if (get_options()->EnforceDistinctSubnets
== 0)
2591 if (tor_addr_family(addr
) == AF_INET
) {
2592 /*XXXX022 IP6 what corresponds to an /24? */
2593 uint32_t ip
= tor_addr_to_ipv4h(addr
);
2595 /* It's possible that this next check will hit before the first time
2596 * resolve_my_address actually succeeds. (For clients, it is likely that
2597 * resolve_my_address will never be called at all). In those cases,
2598 * last_resolved_addr will be 0, and so checking to see whether ip is on
2599 * the same /24 as last_resolved_addr will be the same as checking whether
2600 * it was on net 0, which is already done by is_internal_IP.
2602 if ((last_resolved_addr
& (uint32_t)0xffffff00ul
)
2603 == (ip
& (uint32_t)0xffffff00ul
))
2609 /** Called when we don't have a nickname set. Try to guess a good nickname
2610 * based on the hostname, and return it in a newly allocated string. If we
2611 * can't, return NULL and let the caller warn if it wants to. */
2613 get_default_nickname(void)
2615 static const char * const bad_default_nicknames
[] = {
2619 char localhostname
[256];
2620 char *cp
, *out
, *outp
;
2623 if (gethostname(localhostname
, sizeof(localhostname
)) < 0)
2626 /* Put it in lowercase; stop at the first dot. */
2627 if ((cp
= strchr(localhostname
, '.')))
2629 tor_strlower(localhostname
);
2631 /* Strip invalid characters. */
2633 out
= outp
= tor_malloc(strlen(localhostname
) + 1);
2635 if (strchr(LEGAL_NICKNAME_CHARACTERS
, *cp
))
2642 /* Enforce length. */
2643 if (strlen(out
) > MAX_NICKNAME_LEN
)
2644 out
[MAX_NICKNAME_LEN
]='\0';
2646 /* Check for dumb names. */
2647 for (i
= 0; bad_default_nicknames
[i
]; ++i
) {
2648 if (!strcmp(out
, bad_default_nicknames
[i
])) {
2657 /** Release storage held by <b>options</b>. */
2659 config_free(config_format_t
*fmt
, void *options
)
2668 for (i
=0; fmt
->vars
[i
].name
; ++i
)
2669 option_clear(fmt
, options
, &(fmt
->vars
[i
]));
2671 config_line_t
**linep
= STRUCT_VAR_P(options
, fmt
->extra
->var_offset
);
2672 config_free_lines(*linep
);
2678 /** Return true iff a and b contain identical keys and values in identical
2681 config_lines_eq(config_line_t
*a
, config_line_t
*b
)
2684 if (strcasecmp(a
->key
, b
->key
) || strcmp(a
->value
, b
->value
))
2694 /** Return true iff the option <b>name</b> has the same value in <b>o1</b>
2695 * and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
2698 option_is_same(config_format_t
*fmt
,
2699 or_options_t
*o1
, or_options_t
*o2
, const char *name
)
2701 config_line_t
*c1
, *c2
;
2706 c1
= get_assigned_option(fmt
, o1
, name
, 0);
2707 c2
= get_assigned_option(fmt
, o2
, name
, 0);
2708 r
= config_lines_eq(c1
, c2
);
2709 config_free_lines(c1
);
2710 config_free_lines(c2
);
2714 /** Copy storage held by <b>old</b> into a new or_options_t and return it. */
2715 static or_options_t
*
2716 options_dup(config_format_t
*fmt
, or_options_t
*old
)
2718 or_options_t
*newopts
;
2720 config_line_t
*line
;
2722 newopts
= config_alloc(fmt
);
2723 for (i
=0; fmt
->vars
[i
].name
; ++i
) {
2724 if (fmt
->vars
[i
].type
== CONFIG_TYPE_LINELIST_S
)
2726 if (fmt
->vars
[i
].type
== CONFIG_TYPE_OBSOLETE
)
2728 line
= get_assigned_option(fmt
, old
, fmt
->vars
[i
].name
, 0);
2731 if (config_assign(fmt
, newopts
, line
, 0, 0, &msg
) < 0) {
2732 log_err(LD_BUG
, "Config_get_assigned_option() generated "
2733 "something we couldn't config_assign(): %s", msg
);
2738 config_free_lines(line
);
2743 /** Return a new empty or_options_t. Used for testing. */
2747 return config_alloc(&options_format
);
2750 /** Set <b>options</b> to hold reasonable defaults for most options.
2751 * Each option defaults to zero. */
2753 options_init(or_options_t
*options
)
2755 config_init(&options_format
, options
);
2758 /* Check if the port number given in <b>port_option</b> in combination with
2759 * the specified port in <b>listen_options</b> will result in Tor actually
2760 * opening a low port (meaning a port lower than 1024). Return 1 if
2761 * it is, or 0 if it isn't or the concept of a low port isn't applicable for
2762 * the platform we're on. */
2764 is_listening_on_low_port(uint16_t port_option
,
2765 const config_line_t
*listen_options
)
2769 (void) listen_options
;
2770 return 0; /* No port is too low for windows. */
2772 const config_line_t
*l
;
2774 if (port_option
== 0)
2775 return 0; /* We're not listening */
2776 if (listen_options
== NULL
)
2777 return (port_option
< 1024);
2779 for (l
= listen_options
; l
; l
= l
->next
) {
2780 parse_addr_port(LOG_WARN
, l
->value
, NULL
, NULL
, &p
);
2789 /** Set all vars in the configuration object <b>options</b> to their default
2792 config_init(config_format_t
*fmt
, void *options
)
2796 CHECK(fmt
, options
);
2798 for (i
=0; fmt
->vars
[i
].name
; ++i
) {
2799 var
= &fmt
->vars
[i
];
2800 if (!var
->initvalue
)
2801 continue; /* defaults to NULL or 0 */
2802 option_reset(fmt
, options
, var
, 1);
2806 /** Allocate and return a new string holding the written-out values of the vars
2807 * in 'options'. If 'minimal', do not write out any default-valued vars.
2808 * Else, if comment_defaults, write default values as comments.
2811 config_dump(config_format_t
*fmt
, void *options
, int minimal
,
2812 int comment_defaults
)
2814 smartlist_t
*elements
;
2815 or_options_t
*defaults
;
2816 config_line_t
*line
, *assigned
;
2822 defaults
= config_alloc(fmt
);
2823 config_init(fmt
, defaults
);
2825 /* XXX use a 1 here so we don't add a new log line while dumping */
2826 if (fmt
->validate_fn(NULL
,defaults
, 1, &msg
) < 0) {
2827 log_err(LD_BUG
, "Failed to validate default config.");
2832 elements
= smartlist_create();
2833 for (i
=0; fmt
->vars
[i
].name
; ++i
) {
2834 int comment_option
= 0;
2835 if (fmt
->vars
[i
].type
== CONFIG_TYPE_OBSOLETE
||
2836 fmt
->vars
[i
].type
== CONFIG_TYPE_LINELIST_S
)
2838 /* Don't save 'hidden' control variables. */
2839 if (!strcmpstart(fmt
->vars
[i
].name
, "__"))
2841 if (minimal
&& option_is_same(fmt
, options
, defaults
, fmt
->vars
[i
].name
))
2843 else if (comment_defaults
&&
2844 option_is_same(fmt
, options
, defaults
, fmt
->vars
[i
].name
))
2847 desc
= config_find_description(fmt
, fmt
->vars
[i
].name
);
2848 line
= assigned
= get_assigned_option(fmt
, options
, fmt
->vars
[i
].name
, 1);
2851 /* Only dump the description if there's something to describe. */
2852 wrap_string(elements
, desc
, 78, "# ", "# ");
2855 for (; line
; line
= line
->next
) {
2856 size_t len
= strlen(line
->key
) + strlen(line
->value
) + 5;
2858 tmp
= tor_malloc(len
);
2859 if (tor_snprintf(tmp
, len
, "%s%s %s\n",
2860 comment_option
? "# " : "",
2861 line
->key
, line
->value
)<0) {
2862 log_err(LD_BUG
,"Internal error writing option value");
2865 smartlist_add(elements
, tmp
);
2867 config_free_lines(assigned
);
2871 line
= *(config_line_t
**)STRUCT_VAR_P(options
, fmt
->extra
->var_offset
);
2872 for (; line
; line
= line
->next
) {
2873 size_t len
= strlen(line
->key
) + strlen(line
->value
) + 3;
2875 tmp
= tor_malloc(len
);
2876 if (tor_snprintf(tmp
, len
, "%s %s\n", line
->key
, line
->value
)<0) {
2877 log_err(LD_BUG
,"Internal error writing option value");
2880 smartlist_add(elements
, tmp
);
2884 result
= smartlist_join_strings(elements
, "", 0, NULL
);
2885 SMARTLIST_FOREACH(elements
, char *, cp
, tor_free(cp
));
2886 smartlist_free(elements
);
2887 config_free(fmt
, defaults
);
2891 /** Return a string containing a possible configuration file that would give
2892 * the configuration in <b>options</b>. If <b>minimal</b> is true, do not
2893 * include options that are the same as Tor's defaults.
2896 options_dump(or_options_t
*options
, int minimal
)
2898 return config_dump(&options_format
, options
, minimal
, 0);
2901 /** Return 0 if every element of sl is a string holding a decimal
2902 * representation of a port number, or if sl is NULL.
2903 * Otherwise set *msg and return -1. */
2905 validate_ports_csv(smartlist_t
*sl
, const char *name
, char **msg
)
2914 SMARTLIST_FOREACH(sl
, const char *, cp
,
2917 if (i
< 1 || i
> 65535) {
2918 int r
= tor_snprintf(buf
, sizeof(buf
),
2919 "Port '%s' out of range in %s", cp
, name
);
2920 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
2927 /** If <b>value</b> exceeds ROUTER_MAX_DECLARED_BANDWIDTH, write
2928 * a complaint into *<b>msg</b> using string <b>desc</b>, and return -1.
2932 ensure_bandwidth_cap(uint64_t *value
, const char *desc
, char **msg
)
2936 if (*value
> ROUTER_MAX_DECLARED_BANDWIDTH
) {
2937 /* This handles an understandable special case where somebody says "2gb"
2938 * whereas our actual maximum is 2gb-1 (INT_MAX) */
2941 if (*value
> ROUTER_MAX_DECLARED_BANDWIDTH
) {
2942 r
= tor_snprintf(buf
, sizeof(buf
), "%s ("U64_FORMAT
") must be at most %d",
2943 desc
, U64_PRINTF_ARG(*value
),
2944 ROUTER_MAX_DECLARED_BANDWIDTH
);
2945 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
2951 /** Parse an authority type from <b>options</b>-\>PublishServerDescriptor
2952 * and write it to <b>options</b>-\>_PublishServerDescriptor. Treat "1"
2953 * as "v2,v3" unless BridgeRelay is 1, in which case treat it as "bridge".
2955 * Return 0 on success or -1 if not a recognized authority type (in which
2956 * case the value of _PublishServerDescriptor is undefined). */
2958 compute_publishserverdescriptor(or_options_t
*options
)
2960 smartlist_t
*list
= options
->PublishServerDescriptor
;
2961 authority_type_t
*auth
= &options
->_PublishServerDescriptor
;
2962 *auth
= NO_AUTHORITY
;
2963 if (!list
) /* empty list, answer is none */
2965 SMARTLIST_FOREACH(list
, const char *, string
, {
2966 if (!strcasecmp(string
, "v1"))
2967 *auth
|= V1_AUTHORITY
;
2968 else if (!strcmp(string
, "1"))
2969 if (options
->BridgeRelay
)
2970 *auth
|= BRIDGE_AUTHORITY
;
2972 *auth
|= V2_AUTHORITY
| V3_AUTHORITY
;
2973 else if (!strcasecmp(string
, "v2"))
2974 *auth
|= V2_AUTHORITY
;
2975 else if (!strcasecmp(string
, "v3"))
2976 *auth
|= V3_AUTHORITY
;
2977 else if (!strcasecmp(string
, "bridge"))
2978 *auth
|= BRIDGE_AUTHORITY
;
2979 else if (!strcasecmp(string
, "hidserv"))
2980 *auth
|= HIDSERV_AUTHORITY
;
2981 else if (!strcasecmp(string
, "") || !strcmp(string
, "0"))
2989 /** Lowest allowable value for RendPostPeriod; if this is too low, hidden
2990 * services can overload the directory system. */
2991 #define MIN_REND_POST_PERIOD (10*60)
2993 /** Highest allowable value for RendPostPeriod. */
2994 #define MAX_DIR_PERIOD (MIN_ONION_KEY_LIFETIME/2)
2996 /** Lowest allowable value for MaxCircuitDirtiness; if this is too low, Tor
2997 * will generate too many circuits and potentially overload the network. */
2998 #define MIN_MAX_CIRCUIT_DIRTINESS 10
3000 /** Lowest allowable value for CircuitStreamTimeout; if this is too low, Tor
3001 * will generate too many circuits and potentially overload the network. */
3002 #define MIN_CIRCUIT_STREAM_TIMEOUT 10
3004 /** Return 0 if every setting in <b>options</b> is reasonable, and a
3005 * permissible transition from <b>old_options</b>. Else return -1.
3006 * Should have no side effects, except for normalizing the contents of
3009 * On error, tor_strdup an error explanation into *<b>msg</b>.
3012 * If <b>from_setconf</b>, we were called by the controller, and our
3013 * Log line should stay empty. If it's 0, then give us a default log
3014 * if there are no logs defined.
3017 options_validate(or_options_t
*old_options
, or_options_t
*options
,
3018 int from_setconf
, char **msg
)
3022 const char *uname
= get_uname();
3024 #define REJECT(arg) \
3025 STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
3026 #define COMPLAIN(arg) STMT_BEGIN log(LOG_WARN, LD_CONFIG, arg); STMT_END
3031 if (options
->ORPort
< 0 || options
->ORPort
> 65535)
3032 REJECT("ORPort option out of bounds.");
3034 if (server_mode(options
) &&
3035 (!strcmpstart(uname
, "Windows 95") ||
3036 !strcmpstart(uname
, "Windows 98") ||
3037 !strcmpstart(uname
, "Windows Me"))) {
3038 log(LOG_WARN
, LD_CONFIG
, "Tor is running as a server, but you are "
3039 "running %s; this probably won't work. See "
3040 "https://wiki.torproject.org/TheOnionRouter/TorFAQ#ServerOS "
3041 "for details.", uname
);
3044 if (options
->ORPort
== 0 && options
->ORListenAddress
!= NULL
)
3045 REJECT("ORPort must be defined if ORListenAddress is defined.");
3047 if (options
->DirPort
== 0 && options
->DirListenAddress
!= NULL
)
3048 REJECT("DirPort must be defined if DirListenAddress is defined.");
3050 if (options
->DNSPort
== 0 && options
->DNSListenAddress
!= NULL
)
3051 REJECT("DNSPort must be defined if DNSListenAddress is defined.");
3053 if (options
->ControlPort
== 0 && options
->ControlListenAddress
!= NULL
)
3054 REJECT("ControlPort must be defined if ControlListenAddress is defined.");
3056 if (options
->TransPort
== 0 && options
->TransListenAddress
!= NULL
)
3057 REJECT("TransPort must be defined if TransListenAddress is defined.");
3059 if (options
->NatdPort
== 0 && options
->NatdListenAddress
!= NULL
)
3060 REJECT("NatdPort must be defined if NatdListenAddress is defined.");
3062 /* Don't gripe about SocksPort 0 with SocksListenAddress set; a standard
3063 * configuration does this. */
3065 for (i
= 0; i
< 3; ++i
) {
3066 int is_socks
= i
==0;
3067 int is_trans
= i
==1;
3068 config_line_t
*line
, *opt
, *old
;
3071 opt
= options
->SocksListenAddress
;
3072 old
= old_options
? old_options
->SocksListenAddress
: NULL
;
3074 } else if (is_trans
) {
3075 opt
= options
->TransListenAddress
;
3076 old
= old_options
? old_options
->TransListenAddress
: NULL
;
3077 tp
= "transparent proxy";
3079 opt
= options
->NatdListenAddress
;
3080 old
= old_options
? old_options
->NatdListenAddress
: NULL
;
3084 for (line
= opt
; line
; line
= line
->next
) {
3085 char *address
= NULL
;
3088 if (parse_addr_port(LOG_WARN
, line
->value
, &address
, &addr
, &port
)<0)
3089 continue; /* We'll warn about this later. */
3090 if (!is_internal_IP(addr
, 1) &&
3091 (!old_options
|| !config_lines_eq(old
, opt
))) {
3093 "You specified a public address '%s' for a %s. Other "
3094 "people on the Internet might find your computer and use it as "
3095 "an open %s. Please don't allow this unless you have "
3096 "a good reason.", address
, tp
, tp
);
3102 if (validate_data_directory(options
)<0)
3103 REJECT("Invalid DataDirectory");
3105 if (options
->Nickname
== NULL
) {
3106 if (server_mode(options
)) {
3107 if (!(options
->Nickname
= get_default_nickname())) {
3108 log_notice(LD_CONFIG
, "Couldn't pick a nickname based on "
3109 "our hostname; using %s instead.", UNNAMED_ROUTER_NICKNAME
);
3110 options
->Nickname
= tor_strdup(UNNAMED_ROUTER_NICKNAME
);
3112 log_notice(LD_CONFIG
, "Choosing default nickname '%s'",
3117 if (!is_legal_nickname(options
->Nickname
)) {
3118 r
= tor_snprintf(buf
, sizeof(buf
),
3119 "Nickname '%s' is wrong length or contains illegal characters.",
3121 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
3126 if (server_mode(options
) && !options
->ContactInfo
)
3127 log(LOG_NOTICE
, LD_CONFIG
, "Your ContactInfo config option is not set. "
3128 "Please consider setting it, so we can contact you if your server is "
3129 "misconfigured or something else goes wrong.");
3131 /* Special case on first boot if no Log options are given. */
3132 if (!options
->Logs
&& !options
->RunAsDaemon
&& !from_setconf
)
3133 config_line_append(&options
->Logs
, "Log", "notice stdout");
3135 if (options_init_logs(options
, 1)<0) /* Validate the log(s) */
3136 REJECT("Failed to validate Log options. See logs for details.");
3138 if (options
->NoPublish
) {
3139 log(LOG_WARN
, LD_CONFIG
,
3140 "NoPublish is obsolete. Use PublishServerDescriptor instead.");
3141 SMARTLIST_FOREACH(options
->PublishServerDescriptor
, char *, s
,
3143 smartlist_clear(options
->PublishServerDescriptor
);
3146 if (authdir_mode(options
)) {
3147 /* confirm that our address isn't broken, so we can complain now */
3149 if (resolve_my_address(LOG_WARN
, options
, &tmp
, NULL
) < 0)
3150 REJECT("Failed to resolve/guess local address. See logs for details.");
3154 if (options
->RunAsDaemon
&& torrc_fname
&& path_is_relative(torrc_fname
))
3155 REJECT("Can't use a relative path to torrc when RunAsDaemon is set.");
3158 if (options
->SocksPort
< 0 || options
->SocksPort
> 65535)
3159 REJECT("SocksPort option out of bounds.");
3161 if (options
->DNSPort
< 0 || options
->DNSPort
> 65535)
3162 REJECT("DNSPort option out of bounds.");
3164 if (options
->TransPort
< 0 || options
->TransPort
> 65535)
3165 REJECT("TransPort option out of bounds.");
3167 if (options
->NatdPort
< 0 || options
->NatdPort
> 65535)
3168 REJECT("NatdPort option out of bounds.");
3170 if (options
->SocksPort
== 0 && options
->TransPort
== 0 &&
3171 options
->NatdPort
== 0 && options
->ORPort
== 0 &&
3172 options
->DNSPort
== 0 && !options
->RendConfigLines
)
3173 log(LOG_WARN
, LD_CONFIG
,
3174 "SocksPort, TransPort, NatdPort, DNSPort, and ORPort are all "
3175 "undefined, and there aren't any hidden services configured. "
3176 "Tor will still run, but probably won't do anything.");
3178 if (options
->ControlPort
< 0 || options
->ControlPort
> 65535)
3179 REJECT("ControlPort option out of bounds.");
3181 if (options
->DirPort
< 0 || options
->DirPort
> 65535)
3182 REJECT("DirPort option out of bounds.");
3184 #ifndef USE_TRANSPARENT
3185 if (options
->TransPort
|| options
->TransListenAddress
)
3186 REJECT("TransPort and TransListenAddress are disabled in this build.");
3189 if (options
->AccountingMax
&&
3190 (is_listening_on_low_port(options
->ORPort
, options
->ORListenAddress
) ||
3191 is_listening_on_low_port(options
->DirPort
, options
->DirListenAddress
)))
3193 log(LOG_WARN
, LD_CONFIG
,
3194 "You have set AccountingMax to use hibernation. You have also "
3195 "chosen a low DirPort or OrPort. This combination can make Tor stop "
3196 "working when it tries to re-attach the port after a period of "
3197 "hibernation. Please choose a different port or turn off "
3198 "hibernation unless you know this combination will work on your "
3202 if (options
->ExcludeExitNodes
|| options
->ExcludeNodes
) {
3203 options
->_ExcludeExitNodesUnion
= routerset_new();
3204 routerset_union(options
->_ExcludeExitNodesUnion
,options
->ExcludeExitNodes
);
3205 routerset_union(options
->_ExcludeExitNodesUnion
,options
->ExcludeNodes
);
3208 if (options
->ExcludeNodes
&& options
->StrictNodes
) {
3209 COMPLAIN("You have asked to exclude certain relays from all positions "
3210 "in your circuits. Expect hidden services and other Tor "
3211 "features to be broken in unpredictable ways.");
3214 if (options
->EntryNodes
&& !routerset_is_list(options
->EntryNodes
)) {
3215 /* XXXX fix this; see entry_guards_prepend_from_config(). */
3216 REJECT("IPs or countries are not yet supported in EntryNodes.");
3219 if (options
->AuthoritativeDir
) {
3220 if (!options
->ContactInfo
&& !options
->TestingTorNetwork
)
3221 REJECT("Authoritative directory servers must set ContactInfo");
3222 if (options
->V1AuthoritativeDir
&& !options
->RecommendedVersions
)
3223 REJECT("V1 authoritative dir servers must set RecommendedVersions.");
3224 if (!options
->RecommendedClientVersions
)
3225 options
->RecommendedClientVersions
=
3226 config_lines_dup(options
->RecommendedVersions
);
3227 if (!options
->RecommendedServerVersions
)
3228 options
->RecommendedServerVersions
=
3229 config_lines_dup(options
->RecommendedVersions
);
3230 if (options
->VersioningAuthoritativeDir
&&
3231 (!options
->RecommendedClientVersions
||
3232 !options
->RecommendedServerVersions
))
3233 REJECT("Versioning authoritative dir servers must set "
3234 "Recommended*Versions.");
3235 if (options
->UseEntryGuards
) {
3236 log_info(LD_CONFIG
, "Authoritative directory servers can't set "
3237 "UseEntryGuards. Disabling.");
3238 options
->UseEntryGuards
= 0;
3240 if (!options
->DownloadExtraInfo
&& authdir_mode_any_main(options
)) {
3241 log_info(LD_CONFIG
, "Authoritative directories always try to download "
3242 "extra-info documents. Setting DownloadExtraInfo.");
3243 options
->DownloadExtraInfo
= 1;
3245 if (!(options
->BridgeAuthoritativeDir
|| options
->HSAuthoritativeDir
||
3246 options
->V1AuthoritativeDir
|| options
->V2AuthoritativeDir
||
3247 options
->V3AuthoritativeDir
))
3248 REJECT("AuthoritativeDir is set, but none of "
3249 "(Bridge/HS/V1/V2/V3)AuthoritativeDir is set.");
3250 /* If we have a v3bandwidthsfile and it's broken, complain on startup */
3251 if (options
->V3BandwidthsFile
&& !old_options
) {
3252 dirserv_read_measured_bandwidths(options
->V3BandwidthsFile
, NULL
);
3256 if (options
->AuthoritativeDir
&& !options
->DirPort
)
3257 REJECT("Running as authoritative directory, but no DirPort set.");
3259 if (options
->AuthoritativeDir
&& !options
->ORPort
)
3260 REJECT("Running as authoritative directory, but no ORPort set.");
3262 if (options
->AuthoritativeDir
&& options
->ClientOnly
)
3263 REJECT("Running as authoritative directory, but ClientOnly also set.");
3265 if (options
->FetchDirInfoExtraEarly
&& !options
->FetchDirInfoEarly
)
3266 REJECT("FetchDirInfoExtraEarly requires that you also set "
3267 "FetchDirInfoEarly");
3269 if (options
->ConnLimit
<= 0) {
3270 r
= tor_snprintf(buf
, sizeof(buf
),
3271 "ConnLimit must be greater than 0, but was set to %d",
3272 options
->ConnLimit
);
3273 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
3277 if (validate_ports_csv(options
->FirewallPorts
, "FirewallPorts", msg
) < 0)
3280 if (validate_ports_csv(options
->LongLivedPorts
, "LongLivedPorts", msg
) < 0)
3283 if (validate_ports_csv(options
->RejectPlaintextPorts
,
3284 "RejectPlaintextPorts", msg
) < 0)
3287 if (validate_ports_csv(options
->WarnPlaintextPorts
,
3288 "WarnPlaintextPorts", msg
) < 0)
3291 if (options
->FascistFirewall
&& !options
->ReachableAddresses
) {
3292 if (options
->FirewallPorts
&& smartlist_len(options
->FirewallPorts
)) {
3293 /* We already have firewall ports set, so migrate them to
3294 * ReachableAddresses, which will set ReachableORAddresses and
3295 * ReachableDirAddresses if they aren't set explicitly. */
3296 smartlist_t
*instead
= smartlist_create();
3297 config_line_t
*new_line
= tor_malloc_zero(sizeof(config_line_t
));
3298 new_line
->key
= tor_strdup("ReachableAddresses");
3299 /* If we're configured with the old format, we need to prepend some
3301 SMARTLIST_FOREACH(options
->FirewallPorts
, const char *, portno
,
3303 int p
= atoi(portno
);
3307 tor_snprintf(s
, 16, "*:%d", p
);
3308 smartlist_add(instead
, s
);
3310 new_line
->value
= smartlist_join_strings(instead
,",",0,NULL
);
3311 /* These have been deprecated since 0.1.1.5-alpha-cvs */
3312 log(LOG_NOTICE
, LD_CONFIG
,
3313 "Converting FascistFirewall and FirewallPorts "
3314 "config options to new format: \"ReachableAddresses %s\"",
3316 options
->ReachableAddresses
= new_line
;
3317 SMARTLIST_FOREACH(instead
, char *, cp
, tor_free(cp
));
3318 smartlist_free(instead
);
3320 /* We do not have FirewallPorts set, so add 80 to
3321 * ReachableDirAddresses, and 443 to ReachableORAddresses. */
3322 if (!options
->ReachableDirAddresses
) {
3323 config_line_t
*new_line
= tor_malloc_zero(sizeof(config_line_t
));
3324 new_line
->key
= tor_strdup("ReachableDirAddresses");
3325 new_line
->value
= tor_strdup("*:80");
3326 options
->ReachableDirAddresses
= new_line
;
3327 log(LOG_NOTICE
, LD_CONFIG
, "Converting FascistFirewall config option "
3328 "to new format: \"ReachableDirAddresses *:80\"");
3330 if (!options
->ReachableORAddresses
) {
3331 config_line_t
*new_line
= tor_malloc_zero(sizeof(config_line_t
));
3332 new_line
->key
= tor_strdup("ReachableORAddresses");
3333 new_line
->value
= tor_strdup("*:443");
3334 options
->ReachableORAddresses
= new_line
;
3335 log(LOG_NOTICE
, LD_CONFIG
, "Converting FascistFirewall config option "
3336 "to new format: \"ReachableORAddresses *:443\"");
3341 for (i
=0; i
<3; i
++) {
3342 config_line_t
**linep
=
3343 (i
==0) ? &options
->ReachableAddresses
:
3344 (i
==1) ? &options
->ReachableORAddresses
:
3345 &options
->ReachableDirAddresses
;
3348 /* We need to end with a reject *:*, not an implicit accept *:* */
3350 if (!strcmp((*linep
)->value
, "reject *:*")) /* already there */
3352 linep
= &((*linep
)->next
);
3354 *linep
= tor_malloc_zero(sizeof(config_line_t
));
3355 (*linep
)->key
= tor_strdup(
3356 (i
==0) ? "ReachableAddresses" :
3357 (i
==1) ? "ReachableORAddresses" :
3358 "ReachableDirAddresses");
3359 (*linep
)->value
= tor_strdup("reject *:*");
3365 if ((options
->ReachableAddresses
||
3366 options
->ReachableORAddresses
||
3367 options
->ReachableDirAddresses
) &&
3368 server_mode(options
))
3369 REJECT("Servers must be able to freely connect to the rest "
3370 "of the Internet, so they must not set Reachable*Addresses "
3371 "or FascistFirewall.");
3373 if (options
->UseBridges
&&
3374 server_mode(options
))
3375 REJECT("Servers must be able to freely connect to the rest "
3376 "of the Internet, so they must not set UseBridges.");
3378 options
->_AllowInvalid
= 0;
3379 if (options
->AllowInvalidNodes
) {
3380 SMARTLIST_FOREACH(options
->AllowInvalidNodes
, const char *, cp
, {
3381 if (!strcasecmp(cp
, "entry"))
3382 options
->_AllowInvalid
|= ALLOW_INVALID_ENTRY
;
3383 else if (!strcasecmp(cp
, "exit"))
3384 options
->_AllowInvalid
|= ALLOW_INVALID_EXIT
;
3385 else if (!strcasecmp(cp
, "middle"))
3386 options
->_AllowInvalid
|= ALLOW_INVALID_MIDDLE
;
3387 else if (!strcasecmp(cp
, "introduction"))
3388 options
->_AllowInvalid
|= ALLOW_INVALID_INTRODUCTION
;
3389 else if (!strcasecmp(cp
, "rendezvous"))
3390 options
->_AllowInvalid
|= ALLOW_INVALID_RENDEZVOUS
;
3392 r
= tor_snprintf(buf
, sizeof(buf
),
3393 "Unrecognized value '%s' in AllowInvalidNodes", cp
);
3394 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
3400 if (!options
->SafeLogging
||
3401 !strcasecmp(options
->SafeLogging
, "0")) {
3402 options
->_SafeLogging
= SAFELOG_SCRUB_NONE
;
3403 } else if (!strcasecmp(options
->SafeLogging
, "relay")) {
3404 options
->_SafeLogging
= SAFELOG_SCRUB_RELAY
;
3405 } else if (!strcasecmp(options
->SafeLogging
, "1")) {
3406 options
->_SafeLogging
= SAFELOG_SCRUB_ALL
;
3408 r
= tor_snprintf(buf
, sizeof(buf
),
3409 "Unrecognized value '%s' in SafeLogging",
3410 escaped(options
->SafeLogging
));
3411 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
3415 if (compute_publishserverdescriptor(options
) < 0) {
3416 r
= tor_snprintf(buf
, sizeof(buf
),
3417 "Unrecognized value in PublishServerDescriptor");
3418 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
3422 if ((options
->BridgeRelay
3423 || options
->_PublishServerDescriptor
& BRIDGE_AUTHORITY
)
3424 && (options
->_PublishServerDescriptor
3425 & (V1_AUTHORITY
|V2_AUTHORITY
|V3_AUTHORITY
))) {
3426 REJECT("Bridges are not supposed to publish router descriptors to the "
3427 "directory authorities. Please correct your "
3428 "PublishServerDescriptor line.");
3431 if (options
->MinUptimeHidServDirectoryV2
< 0) {
3432 log_warn(LD_CONFIG
, "MinUptimeHidServDirectoryV2 option must be at "
3433 "least 0 seconds. Changing to 0.");
3434 options
->MinUptimeHidServDirectoryV2
= 0;
3437 if (options
->RendPostPeriod
< MIN_REND_POST_PERIOD
) {
3438 log_warn(LD_CONFIG
, "RendPostPeriod option is too short; "
3439 "raising to %d seconds.", MIN_REND_POST_PERIOD
);
3440 options
->RendPostPeriod
= MIN_REND_POST_PERIOD
;
3443 if (options
->RendPostPeriod
> MAX_DIR_PERIOD
) {
3444 log_warn(LD_CONFIG
, "RendPostPeriod is too large; clipping to %ds.",
3446 options
->RendPostPeriod
= MAX_DIR_PERIOD
;
3449 if (options
->MaxCircuitDirtiness
< MIN_MAX_CIRCUIT_DIRTINESS
) {
3450 log_warn(LD_CONFIG
, "MaxCircuitDirtiness option is too short; "
3451 "raising to %d seconds.", MIN_MAX_CIRCUIT_DIRTINESS
);
3452 options
->MaxCircuitDirtiness
= MIN_MAX_CIRCUIT_DIRTINESS
;
3455 if (options
->CircuitStreamTimeout
&&
3456 options
->CircuitStreamTimeout
< MIN_CIRCUIT_STREAM_TIMEOUT
) {
3457 log_warn(LD_CONFIG
, "CircuitStreamTimeout option is too short; "
3458 "raising to %d seconds.", MIN_CIRCUIT_STREAM_TIMEOUT
);
3459 options
->CircuitStreamTimeout
= MIN_CIRCUIT_STREAM_TIMEOUT
;
3462 if (options
->KeepalivePeriod
< 1)
3463 REJECT("KeepalivePeriod option must be positive.");
3465 if (ensure_bandwidth_cap(&options
->BandwidthRate
,
3466 "BandwidthRate", msg
) < 0)
3468 if (ensure_bandwidth_cap(&options
->BandwidthBurst
,
3469 "BandwidthBurst", msg
) < 0)
3471 if (ensure_bandwidth_cap(&options
->MaxAdvertisedBandwidth
,
3472 "MaxAdvertisedBandwidth", msg
) < 0)
3474 if (ensure_bandwidth_cap(&options
->RelayBandwidthRate
,
3475 "RelayBandwidthRate", msg
) < 0)
3477 if (ensure_bandwidth_cap(&options
->RelayBandwidthBurst
,
3478 "RelayBandwidthBurst", msg
) < 0)
3481 if (server_mode(options
)) {
3482 if (options
->BandwidthRate
< ROUTER_REQUIRED_MIN_BANDWIDTH
) {
3483 r
= tor_snprintf(buf
, sizeof(buf
),
3484 "BandwidthRate is set to %d bytes/second. "
3485 "For servers, it must be at least %d.",
3486 (int)options
->BandwidthRate
,
3487 ROUTER_REQUIRED_MIN_BANDWIDTH
);
3488 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
3490 } else if (options
->MaxAdvertisedBandwidth
<
3491 ROUTER_REQUIRED_MIN_BANDWIDTH
/2) {
3492 r
= tor_snprintf(buf
, sizeof(buf
),
3493 "MaxAdvertisedBandwidth is set to %d bytes/second. "
3494 "For servers, it must be at least %d.",
3495 (int)options
->MaxAdvertisedBandwidth
,
3496 ROUTER_REQUIRED_MIN_BANDWIDTH
/2);
3497 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
3500 if (options
->RelayBandwidthRate
&&
3501 options
->RelayBandwidthRate
< ROUTER_REQUIRED_MIN_BANDWIDTH
) {
3502 r
= tor_snprintf(buf
, sizeof(buf
),
3503 "RelayBandwidthRate is set to %d bytes/second. "
3504 "For servers, it must be at least %d.",
3505 (int)options
->RelayBandwidthRate
,
3506 ROUTER_REQUIRED_MIN_BANDWIDTH
);
3507 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
3512 if (options
->RelayBandwidthRate
&& !options
->RelayBandwidthBurst
)
3513 options
->RelayBandwidthBurst
= options
->RelayBandwidthRate
;
3515 if (options
->RelayBandwidthRate
> options
->RelayBandwidthBurst
)
3516 REJECT("RelayBandwidthBurst must be at least equal "
3517 "to RelayBandwidthRate.");
3519 if (options
->BandwidthRate
> options
->BandwidthBurst
)
3520 REJECT("BandwidthBurst must be at least equal to BandwidthRate.");
3522 /* if they set relaybandwidth* really high but left bandwidth*
3523 * at the default, raise the defaults. */
3524 if (options
->RelayBandwidthRate
> options
->BandwidthRate
)
3525 options
->BandwidthRate
= options
->RelayBandwidthRate
;
3526 if (options
->RelayBandwidthBurst
> options
->BandwidthBurst
)
3527 options
->BandwidthBurst
= options
->RelayBandwidthBurst
;
3529 if (accounting_parse_options(options
, 1)<0)
3530 REJECT("Failed to parse accounting options. See logs for details.");
3532 if (options
->HttpProxy
) { /* parse it now */
3533 if (tor_addr_port_parse(options
->HttpProxy
,
3534 &options
->HttpProxyAddr
, &options
->HttpProxyPort
) < 0)
3535 REJECT("HttpProxy failed to parse or resolve. Please fix.");
3536 if (options
->HttpProxyPort
== 0) { /* give it a default */
3537 options
->HttpProxyPort
= 80;
3541 if (options
->HttpProxyAuthenticator
) {
3542 if (strlen(options
->HttpProxyAuthenticator
) >= 48)
3543 REJECT("HttpProxyAuthenticator is too long (>= 48 chars).");
3546 if (options
->HttpsProxy
) { /* parse it now */
3547 if (tor_addr_port_parse(options
->HttpsProxy
,
3548 &options
->HttpsProxyAddr
, &options
->HttpsProxyPort
) <0)
3549 REJECT("HttpsProxy failed to parse or resolve. Please fix.");
3550 if (options
->HttpsProxyPort
== 0) { /* give it a default */
3551 options
->HttpsProxyPort
= 443;
3555 if (options
->HttpsProxyAuthenticator
) {
3556 if (strlen(options
->HttpsProxyAuthenticator
) >= 48)
3557 REJECT("HttpsProxyAuthenticator is too long (>= 48 chars).");
3560 if (options
->Socks4Proxy
) { /* parse it now */
3561 if (tor_addr_port_parse(options
->Socks4Proxy
,
3562 &options
->Socks4ProxyAddr
,
3563 &options
->Socks4ProxyPort
) <0)
3564 REJECT("Socks4Proxy failed to parse or resolve. Please fix.");
3565 if (options
->Socks4ProxyPort
== 0) { /* give it a default */
3566 options
->Socks4ProxyPort
= 1080;
3570 if (options
->Socks5Proxy
) { /* parse it now */
3571 if (tor_addr_port_parse(options
->Socks5Proxy
,
3572 &options
->Socks5ProxyAddr
,
3573 &options
->Socks5ProxyPort
) <0)
3574 REJECT("Socks5Proxy failed to parse or resolve. Please fix.");
3575 if (options
->Socks5ProxyPort
== 0) { /* give it a default */
3576 options
->Socks5ProxyPort
= 1080;
3580 if (options
->Socks4Proxy
&& options
->Socks5Proxy
)
3581 REJECT("You cannot specify both Socks4Proxy and SOCKS5Proxy");
3583 if (options
->Socks5ProxyUsername
) {
3586 len
= strlen(options
->Socks5ProxyUsername
);
3587 if (len
< 1 || len
> 255)
3588 REJECT("Socks5ProxyUsername must be between 1 and 255 characters.");
3590 if (!options
->Socks5ProxyPassword
)
3591 REJECT("Socks5ProxyPassword must be included with Socks5ProxyUsername.");
3593 len
= strlen(options
->Socks5ProxyPassword
);
3594 if (len
< 1 || len
> 255)
3595 REJECT("Socks5ProxyPassword must be between 1 and 255 characters.");
3596 } else if (options
->Socks5ProxyPassword
)
3597 REJECT("Socks5ProxyPassword must be included with Socks5ProxyUsername.");
3599 if (options
->HashedControlPassword
) {
3600 smartlist_t
*sl
= decode_hashed_passwords(options
->HashedControlPassword
);
3602 REJECT("Bad HashedControlPassword: wrong length or bad encoding");
3604 SMARTLIST_FOREACH(sl
, char*, cp
, tor_free(cp
));
3609 if (options
->HashedControlSessionPassword
) {
3610 smartlist_t
*sl
= decode_hashed_passwords(
3611 options
->HashedControlSessionPassword
);
3613 REJECT("Bad HashedControlSessionPassword: wrong length or bad encoding");
3615 SMARTLIST_FOREACH(sl
, char*, cp
, tor_free(cp
));
3620 if (options
->ControlListenAddress
) {
3621 int all_are_local
= 1;
3623 for (ln
= options
->ControlListenAddress
; ln
; ln
= ln
->next
) {
3624 if (strcmpstart(ln
->value
, "127."))
3627 if (!all_are_local
) {
3628 if (!options
->HashedControlPassword
&&
3629 !options
->HashedControlSessionPassword
&&
3630 !options
->CookieAuthentication
) {
3632 "You have a ControlListenAddress set to accept "
3633 "unauthenticated connections from a non-local address. "
3634 "This means that programs not running on your computer "
3635 "can reconfigure your Tor, without even having to guess a "
3636 "password. That's so bad that I'm closing your ControlPort "
3637 "for you. If you need to control your Tor remotely, try "
3638 "enabling authentication and using a tool like stunnel or "
3639 "ssh to encrypt remote access.");
3640 options
->ControlPort
= 0;
3642 log_warn(LD_CONFIG
, "You have a ControlListenAddress set to accept "
3643 "connections from a non-local address. This means that "
3644 "programs not running on your computer can reconfigure your "
3645 "Tor. That's pretty bad, since the controller "
3646 "protocol isn't encrypted! Maybe you should just listen on "
3647 "127.0.0.1 and use a tool like stunnel or ssh to encrypt "
3648 "remote connections to your control port.");
3653 if (options
->ControlPort
&& !options
->HashedControlPassword
&&
3654 !options
->HashedControlSessionPassword
&&
3655 !options
->CookieAuthentication
) {
3656 log_warn(LD_CONFIG
, "ControlPort is open, but no authentication method "
3657 "has been configured. This means that any program on your "
3658 "computer can reconfigure your Tor. That's bad! You should "
3659 "upgrade your Tor controller as soon as possible.");
3662 if (options
->UseEntryGuards
&& ! options
->NumEntryGuards
)
3663 REJECT("Cannot enable UseEntryGuards with NumEntryGuards set to 0");
3665 if (check_nickname_list(options
->MyFamily
, "MyFamily", msg
))
3667 for (cl
= options
->NodeFamilies
; cl
; cl
= cl
->next
) {
3668 if (check_nickname_list(cl
->value
, "NodeFamily", msg
))
3672 if (validate_addr_policies(options
, msg
) < 0)
3675 if (validate_dir_authorities(options
, old_options
) < 0)
3676 REJECT("Directory authority line did not parse. See logs for details.");
3678 if (options
->UseBridges
&& !options
->Bridges
)
3679 REJECT("If you set UseBridges, you must specify at least one bridge.");
3680 if (options
->UseBridges
&& !options
->TunnelDirConns
)
3681 REJECT("If you set UseBridges, you must set TunnelDirConns.");
3682 if (options
->Bridges
) {
3683 for (cl
= options
->Bridges
; cl
; cl
= cl
->next
) {
3684 if (parse_bridge_line(cl
->value
, 1)<0)
3685 REJECT("Bridge line did not parse. See logs for details.");
3689 if (options
->ConstrainedSockets
) {
3690 /* If the user wants to constrain socket buffer use, make sure the desired
3691 * limit is between MIN|MAX_TCPSOCK_BUFFER in k increments. */
3692 if (options
->ConstrainedSockSize
< MIN_CONSTRAINED_TCP_BUFFER
||
3693 options
->ConstrainedSockSize
> MAX_CONSTRAINED_TCP_BUFFER
||
3694 options
->ConstrainedSockSize
% 1024) {
3695 r
= tor_snprintf(buf
, sizeof(buf
),
3696 "ConstrainedSockSize is invalid. Must be a value between %d and %d "
3697 "in 1024 byte increments.",
3698 MIN_CONSTRAINED_TCP_BUFFER
, MAX_CONSTRAINED_TCP_BUFFER
);
3699 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
3702 if (options
->DirPort
) {
3703 /* Providing cached directory entries while system TCP buffers are scarce
3704 * will exacerbate the socket errors. Suggest that this be disabled. */
3705 COMPLAIN("You have requested constrained socket buffers while also "
3706 "serving directory entries via DirPort. It is strongly "
3707 "suggested that you disable serving directory requests when "
3708 "system TCP buffer resources are scarce.");
3712 if (options
->V3AuthVoteDelay
+ options
->V3AuthDistDelay
>=
3713 options
->V3AuthVotingInterval
/2) {
3714 REJECT("V3AuthVoteDelay plus V3AuthDistDelay must be less than half "
3715 "V3AuthVotingInterval");
3717 if (options
->V3AuthVoteDelay
< MIN_VOTE_SECONDS
)
3718 REJECT("V3AuthVoteDelay is way too low.");
3719 if (options
->V3AuthDistDelay
< MIN_DIST_SECONDS
)
3720 REJECT("V3AuthDistDelay is way too low.");
3722 if (options
->V3AuthNIntervalsValid
< 2)
3723 REJECT("V3AuthNIntervalsValid must be at least 2.");
3725 if (options
->V3AuthVotingInterval
< MIN_VOTE_INTERVAL
) {
3726 REJECT("V3AuthVotingInterval is insanely low.");
3727 } else if (options
->V3AuthVotingInterval
> 24*60*60) {
3728 REJECT("V3AuthVotingInterval is insanely high.");
3729 } else if (((24*60*60) % options
->V3AuthVotingInterval
) != 0) {
3730 COMPLAIN("V3AuthVotingInterval does not divide evenly into 24 hours.");
3733 if (rend_config_services(options
, 1) < 0)
3734 REJECT("Failed to configure rendezvous options. See logs for details.");
3736 /* Parse client-side authorization for hidden services. */
3737 if (rend_parse_service_authorization(options
, 1) < 0)
3738 REJECT("Failed to configure client authorization for hidden services. "
3739 "See logs for details.");
3741 if (parse_virtual_addr_network(options
->VirtualAddrNetwork
, 1, NULL
)<0)
3744 if (options
->PreferTunneledDirConns
&& !options
->TunnelDirConns
)
3745 REJECT("Must set TunnelDirConns if PreferTunneledDirConns is set.");
3747 if ((options
->Socks4Proxy
|| options
->Socks5Proxy
) &&
3748 !options
->HttpProxy
&& !options
->PreferTunneledDirConns
)
3749 REJECT("When Socks4Proxy or Socks5Proxy is configured, "
3750 "PreferTunneledDirConns and TunnelDirConns must both be "
3751 "set to 1, or HttpProxy must be configured.");
3753 if (options
->AutomapHostsSuffixes
) {
3754 SMARTLIST_FOREACH(options
->AutomapHostsSuffixes
, char *, suf
,
3756 size_t len
= strlen(suf
);
3757 if (len
&& suf
[len
-1] == '.')
3762 if (options
->TestingTorNetwork
&& !options
->DirServers
) {
3763 REJECT("TestingTorNetwork may only be configured in combination with "
3764 "a non-default set of DirServers.");
3767 /*XXXX022 checking for defaults manually like this is a bit fragile.*/
3769 /* Keep changes to hard-coded values synchronous to man page and default
3771 if (options
->TestingV3AuthInitialVotingInterval
!= 30*60 &&
3772 !options
->TestingTorNetwork
) {
3773 REJECT("TestingV3AuthInitialVotingInterval may only be changed in testing "
3775 } else if (options
->TestingV3AuthInitialVotingInterval
< MIN_VOTE_INTERVAL
) {
3776 REJECT("TestingV3AuthInitialVotingInterval is insanely low.");
3777 } else if (((30*60) % options
->TestingV3AuthInitialVotingInterval
) != 0) {
3778 REJECT("TestingV3AuthInitialVotingInterval does not divide evenly into "
3782 if (options
->TestingV3AuthInitialVoteDelay
!= 5*60 &&
3783 !options
->TestingTorNetwork
) {
3784 REJECT("TestingV3AuthInitialVoteDelay may only be changed in testing "
3786 } else if (options
->TestingV3AuthInitialVoteDelay
< MIN_VOTE_SECONDS
) {
3787 REJECT("TestingV3AuthInitialVoteDelay is way too low.");
3790 if (options
->TestingV3AuthInitialDistDelay
!= 5*60 &&
3791 !options
->TestingTorNetwork
) {
3792 REJECT("TestingV3AuthInitialDistDelay may only be changed in testing "
3794 } else if (options
->TestingV3AuthInitialDistDelay
< MIN_DIST_SECONDS
) {
3795 REJECT("TestingV3AuthInitialDistDelay is way too low.");
3798 if (options
->TestingV3AuthInitialVoteDelay
+
3799 options
->TestingV3AuthInitialDistDelay
>=
3800 options
->TestingV3AuthInitialVotingInterval
/2) {
3801 REJECT("TestingV3AuthInitialVoteDelay plus TestingV3AuthInitialDistDelay "
3802 "must be less than half TestingV3AuthInitialVotingInterval");
3805 if (options
->TestingAuthDirTimeToLearnReachability
!= 30*60 &&
3806 !options
->TestingTorNetwork
) {
3807 REJECT("TestingAuthDirTimeToLearnReachability may only be changed in "
3808 "testing Tor networks!");
3809 } else if (options
->TestingAuthDirTimeToLearnReachability
< 0) {
3810 REJECT("TestingAuthDirTimeToLearnReachability must be non-negative.");
3811 } else if (options
->TestingAuthDirTimeToLearnReachability
> 2*60*60) {
3812 COMPLAIN("TestingAuthDirTimeToLearnReachability is insanely high.");
3815 if (options
->TestingEstimatedDescriptorPropagationTime
!= 10*60 &&
3816 !options
->TestingTorNetwork
) {
3817 REJECT("TestingEstimatedDescriptorPropagationTime may only be changed in "
3818 "testing Tor networks!");
3819 } else if (options
->TestingEstimatedDescriptorPropagationTime
< 0) {
3820 REJECT("TestingEstimatedDescriptorPropagationTime must be non-negative.");
3821 } else if (options
->TestingEstimatedDescriptorPropagationTime
> 60*60) {
3822 COMPLAIN("TestingEstimatedDescriptorPropagationTime is insanely high.");
3825 if (options
->TestingTorNetwork
) {
3826 log_warn(LD_CONFIG
, "TestingTorNetwork is set. This will make your node "
3827 "almost unusable in the public Tor network, and is "
3828 "therefore only advised if you are building a "
3829 "testing Tor network!");
3832 if (options
->AccelName
&& !options
->HardwareAccel
)
3833 options
->HardwareAccel
= 1;
3834 if (options
->AccelDir
&& !options
->AccelName
)
3835 REJECT("Can't use hardware crypto accelerator dir without engine name.");
3842 /** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
3845 opt_streq(const char *s1
, const char *s2
)
3849 else if (s1
&& s2
&& !strcmp(s1
,s2
))
3855 /** Check if any of the previous options have changed but aren't allowed to. */
3857 options_transition_allowed(or_options_t
*old
, or_options_t
*new_val
,
3863 if (!opt_streq(old
->PidFile
, new_val
->PidFile
)) {
3864 *msg
= tor_strdup("PidFile is not allowed to change.");
3868 if (old
->RunAsDaemon
!= new_val
->RunAsDaemon
) {
3869 *msg
= tor_strdup("While Tor is running, changing RunAsDaemon "
3874 if (strcmp(old
->DataDirectory
,new_val
->DataDirectory
)!=0) {
3876 int r
= tor_snprintf(buf
, sizeof(buf
),
3877 "While Tor is running, changing DataDirectory "
3878 "(\"%s\"->\"%s\") is not allowed.",
3879 old
->DataDirectory
, new_val
->DataDirectory
);
3880 *msg
= tor_strdup(r
>= 0 ? buf
: "internal error");
3884 if (!opt_streq(old
->User
, new_val
->User
)) {
3885 *msg
= tor_strdup("While Tor is running, changing User is not allowed.");
3889 if (!opt_streq(old
->Group
, new_val
->Group
)) {
3890 *msg
= tor_strdup("While Tor is running, changing Group is not allowed.");
3894 if ((old
->HardwareAccel
!= new_val
->HardwareAccel
)
3895 || !opt_streq(old
->AccelName
, new_val
->AccelName
)
3896 || !opt_streq(old
->AccelDir
, new_val
->AccelDir
)) {
3897 *msg
= tor_strdup("While Tor is running, changing OpenSSL hardware "
3898 "acceleration engine is not allowed.");
3902 if (old
->TestingTorNetwork
!= new_val
->TestingTorNetwork
) {
3903 *msg
= tor_strdup("While Tor is running, changing TestingTorNetwork "
3908 if (old
->CellStatistics
!= new_val
->CellStatistics
||
3909 old
->DirReqStatistics
!= new_val
->DirReqStatistics
||
3910 old
->EntryStatistics
!= new_val
->EntryStatistics
||
3911 old
->ExitPortStatistics
!= new_val
->ExitPortStatistics
) {
3912 *msg
= tor_strdup("While Tor is running, changing either "
3913 "CellStatistics, DirReqStatistics, EntryStatistics, "
3914 "or ExitPortStatistics is not allowed.");
3918 if (old
->DisableAllSwap
!= new_val
->DisableAllSwap
) {
3919 *msg
= tor_strdup("While Tor is running, changing DisableAllSwap "
3927 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
3928 * will require us to rotate the CPU and DNS workers; else return 0. */
3930 options_transition_affects_workers(or_options_t
*old_options
,
3931 or_options_t
*new_options
)
3933 if (!opt_streq(old_options
->DataDirectory
, new_options
->DataDirectory
) ||
3934 old_options
->NumCpus
!= new_options
->NumCpus
||
3935 old_options
->ORPort
!= new_options
->ORPort
||
3936 old_options
->ServerDNSSearchDomains
!=
3937 new_options
->ServerDNSSearchDomains
||
3938 old_options
->SafeLogging
!= new_options
->SafeLogging
||
3939 old_options
->ClientOnly
!= new_options
->ClientOnly
||
3940 !config_lines_eq(old_options
->Logs
, new_options
->Logs
))
3943 /* Check whether log options match. */
3945 /* Nothing that changed matters. */
3949 /** Return 1 if any change from <b>old_options</b> to <b>new_options</b>
3950 * will require us to generate a new descriptor; else return 0. */
3952 options_transition_affects_descriptor(or_options_t
*old_options
,
3953 or_options_t
*new_options
)
3955 /* XXX We can be smarter here. If your DirPort isn't being
3956 * published and you just turned it off, no need to republish. Etc. */
3957 if (!opt_streq(old_options
->DataDirectory
, new_options
->DataDirectory
) ||
3958 !opt_streq(old_options
->Nickname
,new_options
->Nickname
) ||
3959 !opt_streq(old_options
->Address
,new_options
->Address
) ||
3960 !config_lines_eq(old_options
->ExitPolicy
,new_options
->ExitPolicy
) ||
3961 old_options
->ExitPolicyRejectPrivate
!=
3962 new_options
->ExitPolicyRejectPrivate
||
3963 old_options
->ORPort
!= new_options
->ORPort
||
3964 old_options
->DirPort
!= new_options
->DirPort
||
3965 old_options
->ClientOnly
!= new_options
->ClientOnly
||
3966 old_options
->NoPublish
!= new_options
->NoPublish
||
3967 old_options
->_PublishServerDescriptor
!=
3968 new_options
->_PublishServerDescriptor
||
3969 get_effective_bwrate(old_options
) != get_effective_bwrate(new_options
) ||
3970 get_effective_bwburst(old_options
) !=
3971 get_effective_bwburst(new_options
) ||
3972 !opt_streq(old_options
->ContactInfo
, new_options
->ContactInfo
) ||
3973 !opt_streq(old_options
->MyFamily
, new_options
->MyFamily
) ||
3974 !opt_streq(old_options
->AccountingStart
, new_options
->AccountingStart
) ||
3975 old_options
->AccountingMax
!= new_options
->AccountingMax
)
3982 /** Return the directory on windows where we expect to find our application
3985 get_windows_conf_root(void)
3987 static int is_set
= 0;
3988 static char path
[MAX_PATH
+1];
3997 /* Find X:\documents and settings\username\application data\ .
3998 * We would use SHGetSpecialFolder path, but that wasn't added until IE4.
4000 #ifdef ENABLE_LOCAL_APPDATA
4001 #define APPDATA_PATH CSIDL_LOCAL_APPDATA
4003 #define APPDATA_PATH CSIDL_APPDATA
4005 if (!SUCCEEDED(SHGetSpecialFolderLocation(NULL
, APPDATA_PATH
, &idl
))) {
4006 GetCurrentDirectory(MAX_PATH
, path
);
4009 "I couldn't find your application data folder: are you "
4010 "running an ancient version of Windows 95? Defaulting to \"%s\"",
4014 /* Convert the path from an "ID List" (whatever that is!) to a path. */
4015 result
= SHGetPathFromIDList(idl
, path
);
4016 /* Now we need to free the */
4019 m
->lpVtbl
->Free(m
, idl
);
4020 m
->lpVtbl
->Release(m
);
4022 if (!SUCCEEDED(result
)) {
4025 strlcat(path
,"\\tor",MAX_PATH
);
4031 /** Return the default location for our torrc file. */
4033 get_default_conf_file(void)
4036 static char path
[MAX_PATH
+1];
4037 strlcpy(path
, get_windows_conf_root(), MAX_PATH
);
4038 strlcat(path
,"\\torrc",MAX_PATH
);
4041 return (CONFDIR
"/torrc");
4045 /** Verify whether lst is a string containing valid-looking comma-separated
4046 * nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
4049 check_nickname_list(const char *lst
, const char *name
, char **msg
)
4056 sl
= smartlist_create();
4058 smartlist_split_string(sl
, lst
, ",",
4059 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
|SPLIT_STRIP_SPACE
, 0);
4061 SMARTLIST_FOREACH(sl
, const char *, s
,
4063 if (!is_legal_nickname_or_hexdigest(s
)) {
4065 int tmp
= tor_snprintf(buf
, sizeof(buf
),
4066 "Invalid nickname '%s' in %s line", s
, name
);
4067 *msg
= tor_strdup(tmp
>= 0 ? buf
: "internal error");
4072 SMARTLIST_FOREACH(sl
, char *, s
, tor_free(s
));
4077 /** Learn config file name from command line arguments, or use the default */
4079 find_torrc_filename(int argc
, char **argv
,
4080 int *using_default_torrc
, int *ignore_missing_torrc
)
4085 for (i
= 1; i
< argc
; ++i
) {
4086 if (i
< argc
-1 && !strcmp(argv
[i
],"-f")) {
4088 log(LOG_WARN
, LD_CONFIG
, "Duplicate -f options on command line.");
4092 /* XXX one day we might want to extend expand_filename to work
4093 * under Windows as well. */
4094 fname
= tor_strdup(argv
[i
+1]);
4096 fname
= expand_filename(argv
[i
+1]);
4098 *using_default_torrc
= 0;
4100 } else if (!strcmp(argv
[i
],"--ignore-missing-torrc")) {
4101 *ignore_missing_torrc
= 1;
4105 if (*using_default_torrc
) {
4106 /* didn't find one, try CONFDIR */
4107 const char *dflt
= get_default_conf_file();
4108 if (dflt
&& file_status(dflt
) == FN_FILE
) {
4109 fname
= tor_strdup(dflt
);
4113 fn
= expand_filename("~/.torrc");
4114 if (fn
&& file_status(fn
) == FN_FILE
) {
4118 fname
= tor_strdup(dflt
);
4121 fname
= tor_strdup(dflt
);
4128 /** Load torrc from disk, setting torrc_fname if successful */
4130 load_torrc_from_disk(int argc
, char **argv
)
4134 int using_default_torrc
= 1;
4135 int ignore_missing_torrc
= 0;
4137 fname
= find_torrc_filename(argc
, argv
,
4138 &using_default_torrc
, &ignore_missing_torrc
);
4140 log(LOG_DEBUG
, LD_CONFIG
, "Opening config file \"%s\"", fname
);
4142 tor_free(torrc_fname
);
4143 torrc_fname
= fname
;
4145 /* Open config file */
4146 if (file_status(fname
) != FN_FILE
||
4147 !(cf
= read_file_to_str(fname
,0,NULL
))) {
4148 if (using_default_torrc
== 1 || ignore_missing_torrc
) {
4149 log(LOG_NOTICE
, LD_CONFIG
, "Configuration file \"%s\" not present, "
4150 "using reasonable defaults.", fname
);
4151 tor_free(fname
); /* sets fname to NULL */
4153 cf
= tor_strdup("");
4155 log(LOG_WARN
, LD_CONFIG
,
4156 "Unable to open configuration file \"%s\".", fname
);
4168 /** Read a configuration file into <b>options</b>, finding the configuration
4169 * file location based on the command line. After loading the file
4170 * call options_init_from_string() to load the config.
4171 * Return 0 if success, -1 if failure. */
4173 options_init_from_torrc(int argc
, char **argv
)
4176 int i
, retval
, command
;
4177 static char **backup_argv
;
4178 static int backup_argc
;
4179 char *command_arg
= NULL
;
4182 if (argv
) { /* first time we're called. save command line args */
4185 } else { /* we're reloading. need to clean up old options first. */
4189 if (argc
> 1 && (!strcmp(argv
[1], "-h") || !strcmp(argv
[1],"--help"))) {
4193 if (argc
> 1 && !strcmp(argv
[1], "--list-torrc-options")) {
4194 /* For documenting validating whether we've documented everything. */
4195 list_torrc_options();
4199 if (argc
> 1 && (!strcmp(argv
[1],"--version"))) {
4200 printf("Tor version %s.\n",get_version());
4203 if (argc
> 1 && (!strcmp(argv
[1],"--digests"))) {
4204 printf("Tor version %s.\n",get_version());
4205 printf("%s", libor_get_digests());
4206 printf("%s", tor_get_digests());
4210 /* Go through command-line variables */
4211 if (!global_cmdline_options
) {
4212 /* Or we could redo the list every time we pass this place.
4213 * It does not really matter */
4214 if (config_get_commandlines(argc
, argv
, &global_cmdline_options
) < 0) {
4219 command
= CMD_RUN_TOR
;
4220 for (i
= 1; i
< argc
; ++i
) {
4221 if (!strcmp(argv
[i
],"--list-fingerprint")) {
4222 command
= CMD_LIST_FINGERPRINT
;
4223 } else if (!strcmp(argv
[i
],"--hash-password")) {
4224 command
= CMD_HASH_PASSWORD
;
4225 command_arg
= tor_strdup( (i
< argc
-1) ? argv
[i
+1] : "");
4227 } else if (!strcmp(argv
[i
],"--verify-config")) {
4228 command
= CMD_VERIFY_CONFIG
;
4232 if (command
== CMD_HASH_PASSWORD
) {
4233 cf
= tor_strdup("");
4235 cf
= load_torrc_from_disk(argc
, argv
);
4240 retval
= options_init_from_string(cf
, command
, command_arg
, &errmsg
);
4249 log(LOG_WARN
,LD_CONFIG
,"%s", errmsg
);
4255 /** Load the options from the configuration in <b>cf</b>, validate
4256 * them for consistency and take actions based on them.
4258 * Return 0 if success, negative on error:
4259 * * -1 for general errors.
4260 * * -2 for failure to parse/validate,
4261 * * -3 for transition not allowed
4262 * * -4 for error while setting the new options
4265 options_init_from_string(const char *cf
,
4266 int command
, const char *command_arg
,
4269 or_options_t
*oldoptions
, *newoptions
;
4272 setopt_err_t err
= SETOPT_ERR_MISC
;
4275 oldoptions
= global_options
; /* get_options unfortunately asserts if
4276 this is the first time we run*/
4278 newoptions
= tor_malloc_zero(sizeof(or_options_t
));
4279 newoptions
->_magic
= OR_OPTIONS_MAGIC
;
4280 options_init(newoptions
);
4281 newoptions
->command
= command
;
4282 newoptions
->command_arg
= command_arg
;
4284 /* get config lines, assign them */
4285 retval
= config_get_lines(cf
, &cl
);
4287 err
= SETOPT_ERR_PARSE
;
4290 retval
= config_assign(&options_format
, newoptions
, cl
, 0, 0, msg
);
4291 config_free_lines(cl
);
4293 err
= SETOPT_ERR_PARSE
;
4297 /* Go through command-line variables too */
4298 retval
= config_assign(&options_format
, newoptions
,
4299 global_cmdline_options
, 0, 0, msg
);
4301 err
= SETOPT_ERR_PARSE
;
4305 /* If this is a testing network configuration, change defaults
4306 * for a list of dependent config options, re-initialize newoptions
4307 * with the new defaults, and assign all options to it second time. */
4308 if (newoptions
->TestingTorNetwork
) {
4309 /* XXXX this is a bit of a kludge. perhaps there's a better way to do
4310 * this? We could, for example, make the parsing algorithm do two passes
4311 * over the configuration. If it finds any "suite" options like
4312 * TestingTorNetwork, it could change the defaults before its second pass.
4313 * Not urgent so long as this seems to work, but at any sign of trouble,
4314 * let's clean it up. -NM */
4316 /* Change defaults. */
4318 for (i
= 0; testing_tor_network_defaults
[i
].name
; ++i
) {
4319 config_var_t
*new_var
= &testing_tor_network_defaults
[i
];
4320 config_var_t
*old_var
=
4321 config_find_option(&options_format
, new_var
->name
);
4322 tor_assert(new_var
);
4323 tor_assert(old_var
);
4324 old_var
->initvalue
= new_var
->initvalue
;
4327 /* Clear newoptions and re-initialize them with new defaults. */
4328 config_free(&options_format
, newoptions
);
4329 newoptions
= tor_malloc_zero(sizeof(or_options_t
));
4330 newoptions
->_magic
= OR_OPTIONS_MAGIC
;
4331 options_init(newoptions
);
4332 newoptions
->command
= command
;
4333 newoptions
->command_arg
= command_arg
;
4335 /* Assign all options a second time. */
4336 retval
= config_get_lines(cf
, &cl
);
4338 err
= SETOPT_ERR_PARSE
;
4341 retval
= config_assign(&options_format
, newoptions
, cl
, 0, 0, msg
);
4342 config_free_lines(cl
);
4344 err
= SETOPT_ERR_PARSE
;
4347 retval
= config_assign(&options_format
, newoptions
,
4348 global_cmdline_options
, 0, 0, msg
);
4350 err
= SETOPT_ERR_PARSE
;
4355 /* Validate newoptions */
4356 if (options_validate(oldoptions
, newoptions
, 0, msg
) < 0) {
4357 err
= SETOPT_ERR_PARSE
; /*XXX make this a separate return value.*/
4361 if (options_transition_allowed(oldoptions
, newoptions
, msg
) < 0) {
4362 err
= SETOPT_ERR_TRANSITION
;
4366 if (set_options(newoptions
, msg
)) {
4367 err
= SETOPT_ERR_SETTING
;
4368 goto err
; /* frees and replaces old options */
4374 config_free(&options_format
, newoptions
);
4376 int len
= (int)strlen(*msg
)+256;
4377 char *newmsg
= tor_malloc(len
);
4379 tor_snprintf(newmsg
, len
, "Failed to parse/validate config: %s", *msg
);
4386 /** Return the location for our configuration file.
4389 get_torrc_fname(void)
4394 return get_default_conf_file();
4397 /** Adjust the address map based on the MapAddress elements in the
4398 * configuration <b>options</b>
4401 config_register_addressmaps(or_options_t
*options
)
4407 addressmap_clear_configured();
4408 elts
= smartlist_create();
4409 for (opt
= options
->AddressMap
; opt
; opt
= opt
->next
) {
4410 smartlist_split_string(elts
, opt
->value
, NULL
,
4411 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 2);
4412 if (smartlist_len(elts
) >= 2) {
4413 from
= smartlist_get(elts
,0);
4414 to
= smartlist_get(elts
,1);
4415 if (address_is_invalid_destination(to
, 1)) {
4417 "Skipping invalid argument '%s' to MapAddress", to
);
4419 addressmap_register(from
, tor_strdup(to
), 0, ADDRMAPSRC_TORRC
);
4420 if (smartlist_len(elts
)>2) {
4421 log_warn(LD_CONFIG
,"Ignoring extra arguments to MapAddress.");
4425 log_warn(LD_CONFIG
,"MapAddress '%s' has too few arguments. Ignoring.",
4428 SMARTLIST_FOREACH(elts
, char*, cp
, tor_free(cp
));
4429 smartlist_clear(elts
);
4431 smartlist_free(elts
);
4435 * Initialize the logs based on the configuration file.
4438 options_init_logs(or_options_t
*options
, int validate_only
)
4447 options
->RunAsDaemon
;
4451 elts
= smartlist_create();
4453 for (opt
= options
->Logs
; opt
; opt
= opt
->next
) {
4454 log_severity_list_t
*severity
;
4455 const char *cfg
= opt
->value
;
4456 severity
= tor_malloc_zero(sizeof(log_severity_list_t
));
4457 if (parse_log_severity_config(&cfg
, severity
) < 0) {
4458 log_warn(LD_CONFIG
, "Couldn't parse log levels in Log option 'Log %s'",
4460 ok
= 0; goto cleanup
;
4463 smartlist_split_string(elts
, cfg
, NULL
,
4464 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 2);
4466 if (smartlist_len(elts
) == 0)
4467 smartlist_add(elts
, tor_strdup("stdout"));
4469 if (smartlist_len(elts
) == 1 &&
4470 (!strcasecmp(smartlist_get(elts
,0), "stdout") ||
4471 !strcasecmp(smartlist_get(elts
,0), "stderr"))) {
4472 int err
= smartlist_len(elts
) &&
4473 !strcasecmp(smartlist_get(elts
,0), "stderr");
4474 if (!validate_only
) {
4477 "Can't log to %s with RunAsDaemon set; skipping stdout",
4478 err
?"stderr":"stdout");
4480 add_stream_log(severity
, err
?"<stderr>":"<stdout>",
4481 fileno(err
?stderr
:stdout
));
4486 if (smartlist_len(elts
) == 1 &&
4487 !strcasecmp(smartlist_get(elts
,0), "syslog")) {
4488 #ifdef HAVE_SYSLOG_H
4489 if (!validate_only
) {
4490 add_syslog_log(severity
);
4493 log_warn(LD_CONFIG
, "Syslog is not supported on this system. Sorry.");
4498 if (smartlist_len(elts
) == 2 &&
4499 !strcasecmp(smartlist_get(elts
,0), "file")) {
4500 if (!validate_only
) {
4501 if (add_file_log(severity
, smartlist_get(elts
, 1)) < 0) {
4502 log_warn(LD_CONFIG
, "Couldn't open file for 'Log %s': %s",
4503 opt
->value
, strerror(errno
));
4510 log_warn(LD_CONFIG
, "Bad syntax on file Log option 'Log %s'",
4512 ok
= 0; goto cleanup
;
4515 SMARTLIST_FOREACH(elts
, char*, cp
, tor_free(cp
));
4516 smartlist_clear(elts
);
4519 smartlist_free(elts
);
4524 /** Read the contents of a Bridge line from <b>line</b>. Return 0
4525 * if the line is well-formed, and -1 if it isn't. If
4526 * <b>validate_only</b> is 0, and the line is well-formed, then add
4527 * the bridge described in the line to our internal bridge list. */
4529 parse_bridge_line(const char *line
, int validate_only
)
4531 smartlist_t
*items
= NULL
;
4533 char *addrport
=NULL
, *fingerprint
=NULL
;
4536 char digest
[DIGEST_LEN
];
4538 items
= smartlist_create();
4539 smartlist_split_string(items
, line
, NULL
,
4540 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, -1);
4541 if (smartlist_len(items
) < 1) {
4542 log_warn(LD_CONFIG
, "Too few arguments to Bridge line.");
4545 addrport
= smartlist_get(items
, 0);
4546 smartlist_del_keeporder(items
, 0);
4547 if (tor_addr_port_parse(addrport
, &addr
, &port
)<0) {
4548 log_warn(LD_CONFIG
, "Error parsing Bridge address '%s'", addrport
);
4553 "Bridge address '%s' has no port; using default port 443.",
4558 if (smartlist_len(items
)) {
4559 fingerprint
= smartlist_join_strings(items
, "", 0, NULL
);
4560 if (strlen(fingerprint
) != HEX_DIGEST_LEN
) {
4561 log_warn(LD_CONFIG
, "Key digest for Bridge is wrong length.");
4564 if (base16_decode(digest
, DIGEST_LEN
, fingerprint
, HEX_DIGEST_LEN
)<0) {
4565 log_warn(LD_CONFIG
, "Unable to decode Bridge key digest.");
4570 if (!validate_only
) {
4571 log_debug(LD_DIR
, "Bridge at %s:%d (%s)", fmt_addr(&addr
),
4573 fingerprint
? fingerprint
: "no key listed");
4574 bridge_add_from_config(&addr
, port
, fingerprint
? digest
: NULL
);
4584 SMARTLIST_FOREACH(items
, char*, s
, tor_free(s
));
4585 smartlist_free(items
);
4587 tor_free(fingerprint
);
4591 /** Read the contents of a DirServer line from <b>line</b>. If
4592 * <b>validate_only</b> is 0, and the line is well-formed, and it
4593 * shares any bits with <b>required_type</b> or <b>required_type</b>
4594 * is 0, then add the dirserver described in the line (minus whatever
4595 * bits it's missing) as a valid authority. Return 0 on success,
4596 * or -1 if the line isn't well-formed or if we can't add it. */
4598 parse_dir_server_line(const char *line
, authority_type_t required_type
,
4601 smartlist_t
*items
= NULL
;
4603 char *addrport
=NULL
, *address
=NULL
, *nickname
=NULL
, *fingerprint
=NULL
;
4604 uint16_t dir_port
= 0, or_port
= 0;
4605 char digest
[DIGEST_LEN
];
4606 char v3_digest
[DIGEST_LEN
];
4607 authority_type_t type
= V2_AUTHORITY
;
4608 int is_not_hidserv_authority
= 0, is_not_v2_authority
= 0;
4610 items
= smartlist_create();
4611 smartlist_split_string(items
, line
, NULL
,
4612 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, -1);
4613 if (smartlist_len(items
) < 1) {
4614 log_warn(LD_CONFIG
, "No arguments on DirServer line.");
4618 if (is_legal_nickname(smartlist_get(items
, 0))) {
4619 nickname
= smartlist_get(items
, 0);
4620 smartlist_del_keeporder(items
, 0);
4623 while (smartlist_len(items
)) {
4624 char *flag
= smartlist_get(items
, 0);
4625 if (TOR_ISDIGIT(flag
[0]))
4627 if (!strcasecmp(flag
, "v1")) {
4628 type
|= (V1_AUTHORITY
| HIDSERV_AUTHORITY
);
4629 } else if (!strcasecmp(flag
, "hs")) {
4630 type
|= HIDSERV_AUTHORITY
;
4631 } else if (!strcasecmp(flag
, "no-hs")) {
4632 is_not_hidserv_authority
= 1;
4633 } else if (!strcasecmp(flag
, "bridge")) {
4634 type
|= BRIDGE_AUTHORITY
;
4635 } else if (!strcasecmp(flag
, "no-v2")) {
4636 is_not_v2_authority
= 1;
4637 } else if (!strcasecmpstart(flag
, "orport=")) {
4639 char *portstring
= flag
+ strlen("orport=");
4640 or_port
= (uint16_t) tor_parse_long(portstring
, 10, 1, 65535, &ok
, NULL
);
4642 log_warn(LD_CONFIG
, "Invalid orport '%s' on DirServer line.",
4644 } else if (!strcasecmpstart(flag
, "v3ident=")) {
4645 char *idstr
= flag
+ strlen("v3ident=");
4646 if (strlen(idstr
) != HEX_DIGEST_LEN
||
4647 base16_decode(v3_digest
, DIGEST_LEN
, idstr
, HEX_DIGEST_LEN
)<0) {
4648 log_warn(LD_CONFIG
, "Bad v3 identity digest '%s' on DirServer line",
4651 type
|= V3_AUTHORITY
;
4654 log_warn(LD_CONFIG
, "Unrecognized flag '%s' on DirServer line",
4658 smartlist_del_keeporder(items
, 0);
4660 if (is_not_hidserv_authority
)
4661 type
&= ~HIDSERV_AUTHORITY
;
4662 if (is_not_v2_authority
)
4663 type
&= ~V2_AUTHORITY
;
4665 if (smartlist_len(items
) < 2) {
4666 log_warn(LD_CONFIG
, "Too few arguments to DirServer line.");
4669 addrport
= smartlist_get(items
, 0);
4670 smartlist_del_keeporder(items
, 0);
4671 if (parse_addr_port(LOG_WARN
, addrport
, &address
, NULL
, &dir_port
)<0) {
4672 log_warn(LD_CONFIG
, "Error parsing DirServer address '%s'", addrport
);
4676 log_warn(LD_CONFIG
, "Missing port in DirServer address '%s'",addrport
);
4680 fingerprint
= smartlist_join_strings(items
, "", 0, NULL
);
4681 if (strlen(fingerprint
) != HEX_DIGEST_LEN
) {
4682 log_warn(LD_CONFIG
, "Key digest for DirServer is wrong length %d.",
4683 (int)strlen(fingerprint
));
4686 if (!strcmp(fingerprint
, "E623F7625FBE0C87820F11EC5F6D5377ED816294")) {
4687 /* a known bad fingerprint. refuse to use it. We can remove this
4688 * clause once Tor 0.1.2.17 is obsolete. */
4689 log_warn(LD_CONFIG
, "Dangerous dirserver line. To correct, erase your "
4690 "torrc file (%s), or reinstall Tor and use the default torrc.",
4694 if (base16_decode(digest
, DIGEST_LEN
, fingerprint
, HEX_DIGEST_LEN
)<0) {
4695 log_warn(LD_CONFIG
, "Unable to decode DirServer key digest.");
4699 if (!validate_only
&& (!required_type
|| required_type
& type
)) {
4701 type
&= required_type
; /* pare down what we think of them as an
4703 log_debug(LD_DIR
, "Trusted %d dirserver at %s:%d (%s)", (int)type
,
4704 address
, (int)dir_port
, (char*)smartlist_get(items
,0));
4705 if (!add_trusted_dir_server(nickname
, address
, dir_port
, or_port
,
4706 digest
, v3_digest
, type
))
4717 SMARTLIST_FOREACH(items
, char*, s
, tor_free(s
));
4718 smartlist_free(items
);
4722 tor_free(fingerprint
);
4726 /** Adjust the value of options->DataDirectory, or fill it in if it's
4727 * absent. Return 0 on success, -1 on failure. */
4729 normalize_data_directory(or_options_t
*options
)
4733 if (options
->DataDirectory
)
4734 return 0; /* all set */
4735 p
= tor_malloc(MAX_PATH
);
4736 strlcpy(p
,get_windows_conf_root(),MAX_PATH
);
4737 options
->DataDirectory
= p
;
4740 const char *d
= options
->DataDirectory
;
4744 if (strncmp(d
,"~/",2) == 0) {
4745 char *fn
= expand_filename(d
);
4747 log_warn(LD_CONFIG
,"Failed to expand filename \"%s\".", d
);
4750 if (!options
->DataDirectory
&& !strcmp(fn
,"/.tor")) {
4751 /* If our homedir is /, we probably don't want to use it. */
4752 /* Default to LOCALSTATEDIR/tor which is probably closer to what we
4755 "Default DataDirectory is \"~/.tor\". This expands to "
4756 "\"%s\", which is probably not what you want. Using "
4757 "\"%s"PATH_SEPARATOR
"tor\" instead
", fn, LOCALSTATEDIR);
4759 fn = tor_strdup(LOCALSTATEDIR PATH_SEPARATOR "tor
");
4761 tor_free(options->DataDirectory);
4762 options->DataDirectory = fn;
4768 /** Check and normalize the value of options->DataDirectory; return 0 if it
4769 * sane, -1 otherwise. */
4771 validate_data_directory(or_options_t *options)
4773 if (normalize_data_directory(options) < 0)
4775 tor_assert(options->DataDirectory);
4776 if (strlen(options->DataDirectory) > (512-128)) {
4777 log_warn(LD_CONFIG, "DataDirectory is too
long.");
4783 /** This string must remain the same forevermore. It is how we
4784 * recognize that the torrc file doesn't need to be backed up. */
4785 #define GENERATED_FILE_PREFIX "# This file was generated by Tor; " \
4786 "if you edit it, comments will not be preserved"
4787 /** This string can change; it tries to give the reader an idea
4788 * that editing this file by hand is not a good plan. */
4789 #define GENERATED_FILE_COMMENT "# The old torrc file was renamed " \
4790 "to torrc.orig.1 or similar, and Tor will ignore it"
4792 /** Save a configuration file for the configuration in <b>options</b>
4793 * into the file <b>fname</b>. If the file already exists, and
4794 * doesn't begin with GENERATED_FILE_PREFIX, rename it. Otherwise
4795 * replace it. Return 0 on success, -1 on failure. */
4797 write_configuration_file(const char *fname, or_options_t *options)
4799 char *old_val=NULL, *new_val=NULL, *new_conf=NULL;
4800 int rename_old = 0, r;
4805 switch (file_status(fname)) {
4807 old_val = read_file_to_str(fname, 0, NULL);
4808 if (strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
4819 "Config file \"%s\" is not a file? Failing.", fname);
4823 if (!(new_conf = options_dump(options, 1))) {
4824 log_warn(LD_BUG, "Couldn't get configuration string");
4828 len = strlen(new_conf)+256;
4829 new_val = tor_malloc(len);
4830 tor_snprintf(new_val, len, "%s\n%s\n\n%s",
4831 GENERATED_FILE_PREFIX, GENERATED_FILE_COMMENT, new_conf);
4835 size_t fn_tmp_len = strlen(fname)+32;
4837 tor_assert(fn_tmp_len > strlen(fname)); /*check for overflow*/
4838 fn_tmp = tor_malloc(fn_tmp_len);
4840 if (tor_snprintf(fn_tmp, fn_tmp_len, "%s.orig.%d", fname, i)<0) {
4841 log_warn(LD_BUG, "tor_snprintf failed inexplicably");
4845 if (file_status(fn_tmp) == FN_NOENT)
4849 log_notice(LD_CONFIG, "Renaming old configuration file to \"%s\"", fn_tmp);
4850 if (rename(fname, fn_tmp) < 0) {
4852 "Couldn't rename configuration file \"%s\" to \"%s\": %s",
4853 fname, fn_tmp, strerror(errno));
4860 if (write_str_to_file(fname, new_val, 0) < 0)
4874 * Save the current configuration file value to disk. Return 0 on
4875 * success, -1 on failure.
4878 options_save_current(void)
4881 /* This fails if we can't write to our configuration file.
4883 * If we try falling back to datadirectory or something, we have a better
4884 * chance of saving the configuration, but a better chance of doing
4885 * something the user never expected. Let's just warn instead. */
4886 return write_configuration_file(torrc_fname, get_options());
4888 return write_configuration_file(get_default_conf_file(), get_options());
4891 /** Mapping from a unit name to a multiplier for converting that unit into a
4893 struct unit_table_t {
4895 uint64_t multiplier;
4898 /** Table to map the names of memory units to the number of bytes they
4900 static struct unit_table_t memory_units[] = {
4907 { "kbytes", 1<<10 },
4908 { "kilobyte", 1<<10 },
4909 { "kilobytes", 1<<10 },
4913 { "mbytes", 1<<20 },
4914 { "megabyte", 1<<20 },
4915 { "megabytes", 1<<20 },
4918 { "gbytes", 1<<30 },
4919 { "gigabyte", 1<<30 },
4920 { "gigabytes", 1<<30 },
4921 { "tb", U64_LITERAL(1)<<40 },
4922 { "terabyte", U64_LITERAL(1)<<40 },
4923 { "terabytes", U64_LITERAL(1)<<40 },
4927 /** Table to map the names of time units to the number of seconds they
4929 static struct unit_table_t time_units[] = {
4937 { "day", 24*60*60 },
4938 { "days", 24*60*60 },
4939 { "week", 7*24*60*60 },
4940 { "weeks", 7*24*60*60 },
4944 /** Parse a string <b>val</b> containing a number, zero or more
4945 * spaces, and an optional unit string. If the unit appears in the
4946 * table <b>u</b>, then multiply the number by the unit multiplier.
4947 * On success, set *<b>ok</b> to 1 and return this product.
4948 * Otherwise, set *<b>ok</b> to 0.
4951 config_parse_units(const char *val, struct unit_table_t *u, int *ok)
4960 v = tor_parse_uint64(val, 10, 0, UINT64_MAX, ok, &cp);
4961 if (!*ok || (cp && *cp == '.')) {
4962 d = tor_parse_double(val, 0, UINT64_MAX, ok, &cp);
4970 v = use_float ? DBL_TO_U64(d) : v;
4974 cp = (char*) eat_whitespace(cp);
4976 for ( ;u->unit;++u) {
4977 if (!strcasecmp(u->unit, cp)) {
4979 v = u->multiplier * d;
4986 log_warn(LD_CONFIG, "Unknown unit '%s'.", cp);
4996 /** Parse a string in the format "number unit", where unit is a unit of
4997 * information (byte, KB, M, etc). On success, set *<b>ok</b> to true
4998 * and return the number of bytes specified. Otherwise, set
4999 * *<b>ok</b> to false and return 0. */
5001 config_parse_memunit(const char *s, int *ok)
5003 uint64_t u = config_parse_units(s, memory_units, ok);
5007 /** Parse a string in the format "number unit", where unit is a unit of time.
5008 * On success, set *<b>ok</b> to true and return the number of seconds in
5009 * the provided interval. Otherwise, set *<b>ok</b> to 0 and return -1.
5012 config_parse_interval(const char *s, int *ok)
5015 r = config_parse_units(s, time_units, ok);
5019 log_warn(LD_CONFIG, "Interval '%s' is too long", s);
5027 * Initialize the libevent library.
5032 const char *badness=NULL;
5034 configure_libevent_logging();
5035 /* If the kernel complains that some method (say, epoll) doesn't
5036 * exist, we don't care about it, since libevent will cope.
5038 suppress_libevent_log_msg("Function not implemented");
5040 tor_check_libevent_header_compatibility();
5042 tor_libevent_initialize();
5044 suppress_libevent_log_msg(NULL);
5046 tor_check_libevent_version(tor_libevent_get_method(),
5047 get_options()->ORPort != 0,
5050 const char *v = tor_libevent_get_version_str();
5051 const char *m = tor_libevent_get_method();
5052 control_event_general_status(LOG_WARN,
5053 "BAD_LIBEVENT VERSION=%s METHOD=%s BADNESS=%s RECOVERED=NO",
5058 /** Return the persistent state struct for this Tor. */
5062 tor_assert(global_state);
5063 return global_state;
5066 /** Return a newly allocated string holding a filename relative to the data
5067 * directory. If <b>sub1</b> is present, it is the first path component after
5068 * the data directory. If <b>sub2</b> is also present, it is the second path
5069 * component after the data directory. If <b>suffix</b> is present, it
5070 * is appended to the filename.
5073 * get_datadir_fname2_suffix("a", NULL, NULL) -> $DATADIR/a
5074 * get_datadir_fname2_suffix("a", NULL, ".tmp") -> $DATADIR/a.tmp
5075 * get_datadir_fname2_suffix("a", "b", ".tmp") -> $DATADIR/a/b/.tmp
5076 * get_datadir_fname2_suffix("a", "b", NULL) -> $DATADIR/a/b
5078 * Note: Consider using the get_datadir_fname* macros in or.h.
5081 options_get_datadir_fname2_suffix(or_options_t *options,
5082 const char *sub1, const char *sub2,
5087 tor_assert(options);
5088 tor_assert(options->DataDirectory);
5089 tor_assert(sub1 || !sub2); /* If sub2 is present, sub1 must be present. */
5090 len = strlen(options->DataDirectory);
5092 len += strlen(sub1)+1;
5094 len += strlen(sub2)+1;
5097 len += strlen(suffix);
5099 fname = tor_malloc(len);
5102 tor_snprintf(fname, len, "%s"PATH_SEPARATOR"%s"PATH_SEPARATOR"%s",
5103 options->DataDirectory, sub1, sub2);
5105 tor_snprintf(fname, len, "%s"PATH_SEPARATOR"%s",
5106 options->DataDirectory, sub1);
5109 strlcpy(fname, options->DataDirectory, len);
5112 strlcat(fname, suffix, len);
5116 /** Return 0 if every setting in <b>state</b> is reasonable, and a
5117 * permissible transition from <b>old_state</b>. Else warn and return -1.
5118 * Should have no side effects, except for normalizing the contents of
5121 /* XXX from_setconf is here because of bug 238 */
5123 or_state_validate(or_state_t *old_state, or_state_t *state,
5124 int from_setconf, char **msg)
5126 /* We don't use these; only options do. Still, we need to match that
5128 (void) from_setconf;
5131 if (entry_guards_parse_state(state, 0, msg)<0)
5137 /** Replace the current persistent state with <b>new_state</b> */
5139 or_state_set(or_state_t *new_state)
5142 tor_assert(new_state);
5143 config_free(&state_format, global_state);
5144 global_state = new_state;
5145 if (entry_guards_parse_state(global_state, 1, &err)<0) {
5146 log_warn(LD_GENERAL,"%s",err);
5149 if (rep_hist_load_state(global_state, &err)<0) {
5150 log_warn(LD_GENERAL,"Unparseable bandwidth history state: %s",err);
5153 if (circuit_build_times_parse_state(&circ_times, global_state, &err) < 0) {
5154 log_warn(LD_GENERAL,"%s",err);
5159 /** Reload the persistent state from disk, generating a new state as needed.
5160 * Return 0 on success, less than 0 on failure.
5165 or_state_t *new_state = NULL;
5166 char *contents = NULL, *fname;
5167 char *errmsg = NULL;
5168 int r = -1, badstate = 0;
5170 fname = get_datadir_fname("state");
5171 switch (file_status(fname)) {
5173 if (!(contents = read_file_to_str(fname, 0, NULL))) {
5174 log_warn(LD_FS, "Unable to read state file \"%s\"", fname);
5183 log_warn(LD_GENERAL,"State file \"%s\" is not a file? Failing.", fname);
5186 new_state = tor_malloc_zero(sizeof(or_state_t));
5187 new_state->_magic = OR_STATE_MAGIC;
5188 config_init(&state_format, new_state);
5190 config_line_t *lines=NULL;
5192 if (config_get_lines(contents, &lines)<0)
5194 assign_retval = config_assign(&state_format, new_state,
5195 lines, 0, 0, &errmsg);
5196 config_free_lines(lines);
5197 if (assign_retval<0)
5200 log_warn(LD_GENERAL, "%s", errmsg);
5205 if (!badstate && or_state_validate(NULL, new_state, 1, &errmsg) < 0)
5209 log_warn(LD_GENERAL, "%s", errmsg);
5213 if (badstate && !contents) {
5214 log_warn(LD_BUG, "Uh oh. We couldn't even validate our own default state."
5215 " This is a bug in Tor.");
5217 } else if (badstate && contents) {
5219 file_status_t status;
5220 size_t len = strlen(fname)+16;
5221 char *fname2 = tor_malloc(len);
5222 for (i = 0; i < 100; ++i) {
5223 tor_snprintf(fname2, len, "%s.%d", fname, i);
5224 status = file_status(fname2);
5225 if (status == FN_NOENT)
5229 log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad "
5230 "state files to move aside. Discarding the old state file.",
5234 log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside "
5235 "to \"%s\". This could be a bug in Tor; please tell "
5236 "the developers.", fname, fname2);
5237 if (rename(fname, fname2) < 0) {
5238 log_warn(LD_BUG, "Weirdly, I couldn't even move the state aside. The "
5239 "OS gave an error of %s", strerror(errno));
5244 config_free(&state_format, new_state);
5246 new_state = tor_malloc_zero(sizeof(or_state_t));
5247 new_state->_magic = OR_STATE_MAGIC;
5248 config_init(&state_format, new_state);
5249 } else if (contents) {
5250 log_info(LD_GENERAL, "Loaded state from \"%s\"", fname);
5252 log_info(LD_GENERAL, "Initialized state");
5254 or_state_set(new_state);
5257 global_state->next_write = 0;
5258 or_state_save(time(NULL));
5266 config_free(&state_format, new_state);
5271 /** Write the persistent state to disk. Return 0 for success, <0 on failure. */
5273 or_state_save(time_t now)
5275 char *state, *contents;
5276 char tbuf[ISO_TIME_LEN+1];
5280 tor_assert(global_state);
5282 if (global_state->next_write > now)
5285 /* Call everything else that might dirty the state even more, in order
5286 * to avoid redundant writes. */
5287 entry_guards_update_state(global_state);
5288 rep_hist_update_state(global_state);
5289 circuit_build_times_update_state(&circ_times, global_state);
5290 if (accounting_is_enabled(get_options()))
5291 accounting_run_housekeeping(now);
5293 global_state->LastWritten = time(NULL);
5294 tor_free(global_state->TorVersion);
5295 len = strlen(get_version())+8;
5296 global_state->TorVersion = tor_malloc(len);
5297 tor_snprintf(global_state->TorVersion, len, "Tor %s", get_version());
5299 state = config_dump(&state_format, global_state, 1, 0);
5300 len = strlen(state)+256;
5301 contents = tor_malloc(len);
5302 format_local_iso_time(tbuf, time(NULL));
5303 tor_snprintf(contents, len,
5304 "# Tor state file last generated on %s local time\n"
5305 "# Other times below are in GMT\n"
5306 "# You *do not* need to edit this file.\n\n%s",
5309 fname = get_datadir_fname("state");
5310 if (write_str_to_file(fname, contents, 0)<0) {
5311 log_warn(LD_FS, "Unable to write state to file \"%s\"", fname);
5316 log_info(LD_GENERAL, "Saved state to \"%s\"", fname);
5320 global_state->next_write = TIME_MAX;
5324 /** Given a file name check to see whether the file exists but has not been
5325 * modified for a very long time. If so, remove it. */
5327 remove_file_if_very_old(const char *fname, time_t now)
5329 #define VERY_OLD_FILE_AGE (28*24*60*60)
5332 if (stat(fname, &st)==0 && st.st_mtime < now-VERY_OLD_FILE_AGE) {
5333 char buf[ISO_TIME_LEN+1];
5334 format_local_iso_time(buf, st.st_mtime);
5335 log_notice(LD_GENERAL, "Obsolete file %s hasn't been modified since %s. "
5336 "Removing it.", fname, buf);
5341 /** Helper to implement GETINFO functions about configuration variables (not
5342 * their values). Given a "config/names" question, set *<b>answer</b> to a
5343 * new string describing the supported configuration variables and their
5346 getinfo_helper_config(control_connection_t *conn,
5347 const char *question, char **answer)
5350 if (!strcmp(question, "config/names")) {
5351 smartlist_t *sl = smartlist_create();
5353 for (i = 0; _option_vars[i].name; ++i) {
5354 config_var_t *var = &_option_vars[i];
5355 const char *type, *desc;
5358 desc = config_find_description(&options_format, var->name);
5359 switch (var->type) {
5360 case CONFIG_TYPE_STRING: type = "String"; break;
5361 case CONFIG_TYPE_FILENAME: type = "Filename"; break;
5362 case CONFIG_TYPE_UINT: type = "Integer"; break;
5363 case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break;
5364 case CONFIG_TYPE_MEMUNIT: type = "DataSize"; break;
5365 case CONFIG_TYPE_DOUBLE: type = "Float"; break;
5366 case CONFIG_TYPE_BOOL: type = "Boolean"; break;
5367 case CONFIG_TYPE_ISOTIME: type = "Time"; break;
5368 case CONFIG_TYPE_ROUTERSET: type = "RouterList"; break;
5369 case CONFIG_TYPE_CSV: type = "CommaList"; break;
5370 case CONFIG_TYPE_LINELIST: type = "LineList"; break;
5371 case CONFIG_TYPE_LINELIST_S: type = "Dependant"; break;
5372 case CONFIG_TYPE_LINELIST_V: type = "Virtual"; break;
5374 case CONFIG_TYPE_OBSOLETE:
5379 len = strlen(var->name)+strlen(type)+16;
5381 len += strlen(desc);
5382 line = tor_malloc(len);
5384 tor_snprintf(line, len, "%s %s %s\n",var->name,type,desc);
5386 tor_snprintf(line, len, "%s %s\n",var->name,type);
5387 smartlist_add(sl, line);
5389 *answer = smartlist_join_strings(sl, "", 0, NULL);
5390 SMARTLIST_FOREACH(sl, char *, c, tor_free(c));