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-2021, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
8 * @file dirauth_config.c
9 * @brief Code to interpret the user's configuration of Tor's directory
14 #include "feature/dirauth/dirauth_config.h"
16 #include "lib/encoding/confline.h"
17 #include "lib/confmgt/confmgt.h"
18 #include "lib/conf/confdecl.h"
20 /* Required for dirinfo_type_t in or_options_t */
21 #include "core/or/or.h"
22 #include "app/config/config.h"
23 #include "app/config/resolve_addr.h"
25 #include "feature/dirauth/voting_schedule.h"
26 #include "feature/stats/rephist.h"
28 #include "feature/dirauth/authmode.h"
29 #include "feature/dirauth/bwauth.h"
30 #include "feature/dirauth/dirauth_periodic.h"
31 #include "feature/dirauth/dirauth_sys.h"
32 #include "feature/dirauth/dirvote.h"
33 #include "feature/dirauth/guardfraction.h"
34 #include "feature/dirauth/dirauth_options_st.h"
36 /* Copied from config.c, we will refactor later in 29211. */
38 STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
39 #if defined(__GNUC__) && __GNUC__ <= 3
40 #define COMPLAIN(args...) \
41 STMT_BEGIN log_warn(LD_CONFIG, args); STMT_END
43 #define COMPLAIN(args, ...) \
44 STMT_BEGIN log_warn(LD_CONFIG, args, ##__VA_ARGS__); STMT_END
45 #endif /* defined(__GNUC__) && __GNUC__ <= 3 */
47 #define YES_IF_CHANGED_INT(opt) \
48 if (!CFG_EQ_INT(old_options, new_options, opt)) return 1;
50 /** Return true iff we are configured to reject request under load for non
51 * relay connections. */
53 dirauth_should_reject_requests_under_load(void)
55 return !!dirauth_get_options()->AuthDirRejectRequestsUnderLoad
;
59 * Legacy validation/normalization function for the dirauth mode options in
60 * options. Uses old_options as the previous options.
62 * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
66 options_validate_dirauth_mode(const or_options_t
*old_options
,
67 or_options_t
*options
,
76 if (!authdir_mode(options
))
79 /* confirm that our address isn't broken, so we can complain now */
81 if (!find_my_address(options
, AF_INET
, LOG_WARN
, &tmp
, NULL
, NULL
))
82 REJECT("Failed to resolve/guess local address. See logs for details.");
84 if (!options
->ContactInfo
&& !options
->TestingTorNetwork
)
85 REJECT("Authoritative directory servers must set ContactInfo");
87 if (options
->UseEntryGuards
) {
88 log_info(LD_CONFIG
, "Authoritative directory servers can't set "
89 "UseEntryGuards. Disabling.");
90 options
->UseEntryGuards
= 0;
92 if (!options
->DownloadExtraInfo
&& authdir_mode_v3(options
)) {
93 log_info(LD_CONFIG
, "Authoritative directories always try to download "
94 "extra-info documents. Setting DownloadExtraInfo.");
95 options
->DownloadExtraInfo
= 1;
97 if (!(options
->BridgeAuthoritativeDir
||
98 options
->V3AuthoritativeDir
))
99 REJECT("AuthoritativeDir is set, but none of "
100 "(Bridge/V3)AuthoritativeDir is set.");
102 /* If we have a v3bandwidthsfile and it's broken, complain on startup */
103 if (options
->V3BandwidthsFile
&& !old_options
) {
104 dirserv_read_measured_bandwidths(options
->V3BandwidthsFile
, NULL
, NULL
,
107 /* same for guardfraction file */
108 if (options
->GuardfractionFile
&& !old_options
) {
109 dirserv_read_guardfraction_file(options
->GuardfractionFile
, NULL
);
112 if (!options
->DirPort_set
)
113 REJECT("Running as authoritative directory, but no DirPort set.");
115 if (!options
->ORPort_set
)
116 REJECT("Running as authoritative directory, but no ORPort set.");
118 if (options
->ClientOnly
)
119 REJECT("Running as authoritative directory, but ClientOnly also set.");
125 * Legacy validation/normalization function for the dirauth schedule options
126 * in options. Uses old_options as the previous options.
128 * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
132 options_validate_dirauth_schedule(const or_options_t
*old_options
,
133 or_options_t
*options
,
144 if (!authdir_mode_v3(options
))
147 if (options
->V3AuthVoteDelay
+ options
->V3AuthDistDelay
>=
148 options
->V3AuthVotingInterval
/2) {
149 REJECT("V3AuthVoteDelay plus V3AuthDistDelay must be less than half "
150 "V3AuthVotingInterval");
153 if (options
->V3AuthVoteDelay
< MIN_VOTE_SECONDS
) {
154 if (options
->TestingTorNetwork
) {
155 if (options
->V3AuthVoteDelay
< MIN_VOTE_SECONDS_TESTING
) {
156 REJECT("V3AuthVoteDelay is way too low.");
158 COMPLAIN("V3AuthVoteDelay is very low. "
159 "This may lead to failure to vote for a consensus.");
162 REJECT("V3AuthVoteDelay is way too low.");
166 if (options
->V3AuthDistDelay
< MIN_DIST_SECONDS
) {
167 if (options
->TestingTorNetwork
) {
168 if (options
->V3AuthDistDelay
< MIN_DIST_SECONDS_TESTING
) {
169 REJECT("V3AuthDistDelay is way too low.");
171 COMPLAIN("V3AuthDistDelay is very low. "
172 "This may lead to missing votes in a consensus.");
175 REJECT("V3AuthDistDelay is way too low.");
179 if (options
->V3AuthNIntervalsValid
< 2)
180 REJECT("V3AuthNIntervalsValid must be at least 2.");
182 if (options
->V3AuthVotingInterval
< MIN_VOTE_INTERVAL
) {
183 if (options
->TestingTorNetwork
) {
184 if (options
->V3AuthVotingInterval
< MIN_VOTE_INTERVAL_TESTING
) {
185 /* Unreachable, covered by earlier checks */
186 REJECT("V3AuthVotingInterval is insanely low."); /* LCOV_EXCL_LINE */
188 COMPLAIN("V3AuthVotingInterval is very low. "
189 "This may lead to failure to synchronise for a consensus.");
192 REJECT("V3AuthVotingInterval is insanely low.");
194 } else if (options
->V3AuthVotingInterval
> 24*60*60) {
195 REJECT("V3AuthVotingInterval is insanely high.");
196 } else if (((24*60*60) % options
->V3AuthVotingInterval
) != 0) {
197 COMPLAIN("V3AuthVotingInterval does not divide evenly into 24 hours.");
204 * Legacy validation/normalization function for the dirauth testing options
205 * in options. Uses old_options as the previous options.
207 * Returns 0 on success, returns -1 and sets *msg to a newly allocated string
211 options_validate_dirauth_testing(const or_options_t
*old_options
,
212 or_options_t
*options
,
223 if (!authdir_mode(options
))
226 if (!authdir_mode_v3(options
))
229 if (options
->TestingV3AuthInitialVotingInterval
230 < MIN_VOTE_INTERVAL_TESTING_INITIAL
) {
231 REJECT("TestingV3AuthInitialVotingInterval is insanely low.");
232 } else if (((30*60) % options
->TestingV3AuthInitialVotingInterval
) != 0) {
233 REJECT("TestingV3AuthInitialVotingInterval does not divide evenly into "
237 if (options
->TestingV3AuthInitialVoteDelay
< MIN_VOTE_SECONDS_TESTING
) {
238 REJECT("TestingV3AuthInitialVoteDelay is way too low.");
241 if (options
->TestingV3AuthInitialDistDelay
< MIN_DIST_SECONDS_TESTING
) {
242 REJECT("TestingV3AuthInitialDistDelay is way too low.");
245 if (options
->TestingV3AuthInitialVoteDelay
+
246 options
->TestingV3AuthInitialDistDelay
>=
247 options
->TestingV3AuthInitialVotingInterval
) {
248 REJECT("TestingV3AuthInitialVoteDelay plus TestingV3AuthInitialDistDelay "
249 "must be less than TestingV3AuthInitialVotingInterval");
252 if (options
->TestingV3AuthVotingStartOffset
>
253 MIN(options
->TestingV3AuthInitialVotingInterval
,
254 options
->V3AuthVotingInterval
)) {
255 REJECT("TestingV3AuthVotingStartOffset is higher than the voting "
257 } else if (options
->TestingV3AuthVotingStartOffset
< 0) {
258 REJECT("TestingV3AuthVotingStartOffset must be non-negative.");
265 * Return true if changing the configuration from <b>old</b> to <b>new</b>
266 * affects the timing of the voting subsystem
269 options_transition_affects_dirauth_timing(const or_options_t
*old_options
,
270 const or_options_t
*new_options
)
272 tor_assert(old_options
);
273 tor_assert(new_options
);
275 if (authdir_mode_v3(old_options
) != authdir_mode_v3(new_options
))
277 if (! authdir_mode_v3(new_options
))
280 YES_IF_CHANGED_INT(V3AuthVotingInterval
);
281 YES_IF_CHANGED_INT(V3AuthVoteDelay
);
282 YES_IF_CHANGED_INT(V3AuthDistDelay
);
283 YES_IF_CHANGED_INT(TestingV3AuthInitialVotingInterval
);
284 YES_IF_CHANGED_INT(TestingV3AuthInitialVoteDelay
);
285 YES_IF_CHANGED_INT(TestingV3AuthInitialDistDelay
);
286 YES_IF_CHANGED_INT(TestingV3AuthVotingStartOffset
);
291 /** Fetch the active option list, and take dirauth actions based on it. All of
292 * the things we do should survive being done repeatedly. If present,
293 * <b>old_options</b> contains the previous value of the options.
295 * Return 0 if all goes well, return -1 if it's time to die.
297 * Note: We haven't moved all the "act on new configuration" logic
298 * into the options_act* functions yet. Some is still in do_hup() and other
302 options_act_dirauth(const or_options_t
*old_options
)
304 const or_options_t
*options
= get_options();
306 /* We may need to reschedule some dirauth stuff if our status changed. */
308 if (options_transition_affects_dirauth_timing(old_options
, options
)) {
309 dirauth_sched_recalculate_timing(options
, time(NULL
));
310 reschedule_dirvote(options
);
317 /** Fetch the active option list, and take dirauth mtbf actions based on it.
318 * All of the things we do should survive being done repeatedly. If present,
319 * <b>old_options</b> contains the previous value of the options.
321 * Must be called immediately after a successful or_state_load().
323 * Return 0 if all goes well, return -1 if it's time to die.
325 * Note: We haven't moved all the "act on new configuration" logic
326 * into the options_act* functions yet. Some is still in do_hup() and other
330 options_act_dirauth_mtbf(const or_options_t
*old_options
)
334 const or_options_t
*options
= get_options();
335 int running_tor
= options
->command
== CMD_RUN_TOR
;
337 if (!authdir_mode(options
))
340 /* Load dirauth state */
342 rep_hist_load_mtbf_data(time(NULL
));
348 /** Fetch the active option list, and take dirauth statistics actions based
349 * on it. All of the things we do should survive being done repeatedly. If
350 * present, <b>old_options</b> contains the previous value of the options.
352 * Sets <b>*print_notice_out</b> if we enabled stats, and need to print
353 * a stats log using options_act_relay_stats_msg().
355 * Return 0 if all goes well, return -1 if it's time to die.
357 * Note: We haven't moved all the "act on new configuration" logic
358 * into the options_act* functions yet. Some is still in do_hup() and other
362 options_act_dirauth_stats(const or_options_t
*old_options
,
363 bool *print_notice_out
)
365 if (BUG(!print_notice_out
))
368 const or_options_t
*options
= get_options();
370 if (authdir_mode_bridge(options
)) {
371 time_t now
= time(NULL
);
372 int print_notice
= 0;
374 if (!old_options
|| !authdir_mode_bridge(old_options
)) {
375 rep_hist_desc_stats_init(now
);
379 *print_notice_out
= 1;
382 /* If we used to have statistics enabled but we just disabled them,
383 stop gathering them. */
384 if (old_options
&& authdir_mode_bridge(old_options
) &&
385 !authdir_mode_bridge(options
))
386 rep_hist_desc_stats_term();
392 * Make any necessary modifications to a dirauth_options_t that occur
393 * before validation. On success return 0; on failure return -1 and
394 * set *<b>msg_out</b> to a newly allocated error string.
397 dirauth_options_pre_normalize(void *arg
, char **msg_out
)
399 dirauth_options_t
*options
= arg
;
402 if (!options
->RecommendedClientVersions
)
403 options
->RecommendedClientVersions
=
404 config_lines_dup(options
->RecommendedVersions
);
405 if (!options
->RecommendedServerVersions
)
406 options
->RecommendedServerVersions
=
407 config_lines_dup(options
->RecommendedVersions
);
409 if (config_ensure_bandwidth_cap(&options
->AuthDirFastGuarantee
,
410 "AuthDirFastGuarantee", msg_out
) < 0)
412 if (config_ensure_bandwidth_cap(&options
->AuthDirGuardBWGuarantee
,
413 "AuthDirGuardBWGuarantee", msg_out
) < 0)
420 * Check whether a dirauth_options_t is correct.
422 * On success return 0; on failure return -1 and set *<b>msg_out</b> to a
423 * newly allocated error string.
426 dirauth_options_validate(const void *arg
, char **msg
)
428 const dirauth_options_t
*options
= arg
;
430 if (options
->VersioningAuthoritativeDirectory
&&
431 (!options
->RecommendedClientVersions
||
432 !options
->RecommendedServerVersions
)) {
433 REJECT("Versioning authoritative dir servers must set "
434 "Recommended*Versions.");
438 /* Call these functions to produce warnings only. */
439 t
= format_recommended_version_list(options
->RecommendedClientVersions
, 1);
441 t
= format_recommended_version_list(options
->RecommendedServerVersions
, 1);
444 if (options
->TestingAuthDirTimeToLearnReachability
> 2*60*60) {
445 COMPLAIN("TestingAuthDirTimeToLearnReachability is insanely high.");
451 /* Declare the options field table for dirauth_options */
452 #define CONF_CONTEXT TABLE
453 #include "feature/dirauth/dirauth_options.inc"
456 /** Magic number for dirauth_options_t. */
457 #define DIRAUTH_OPTIONS_MAGIC 0x41757448
460 * Declare the configuration options for the dirauth module.
462 const config_format_t dirauth_options_fmt
= {
463 .size
= sizeof(dirauth_options_t
),
464 .magic
= { "dirauth_options_t",
465 DIRAUTH_OPTIONS_MAGIC
,
466 offsetof(dirauth_options_t
, magic
) },
467 .vars
= dirauth_options_t_vars
,
469 .pre_normalize_fn
= dirauth_options_pre_normalize
,
470 .validate_fn
= dirauth_options_validate