aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2019-12-19 07:55:06 -0500
committerNick Mathewson <nickm@torproject.org>2019-12-19 07:55:06 -0500
commita6ba56761b6dc22011eee015f371d37d7b399a64 (patch)
tree77a53e71a12098296a8931342679fc9fbfa36222
parent5c98a42f491145a0d706ba01bfc1947477f76534 (diff)
parent13df7449217cec5d4a9baf73adec850614b43633 (diff)
downloadtor-a6ba56761b6dc22011eee015f371d37d7b399a64.tar.gz
tor-a6ba56761b6dc22011eee015f371d37d7b399a64.zip
Merge branch 'dirauth_config_squashed'
-rw-r--r--src/app/config/config.c1
-rw-r--r--src/app/config/or_options_st.h2
-rw-r--r--src/app/main/subsystem_list.c4
-rw-r--r--src/core/include.am15
-rw-r--r--src/feature/dirauth/.may_include1
-rw-r--r--src/feature/dirauth/dirauth_config.c22
-rw-r--r--src/feature/dirauth/dirauth_config.h2
-rw-r--r--src/feature/dirauth/dirauth_options.inc18
-rw-r--r--src/feature/dirauth/dirauth_options_st.h22
-rw-r--r--src/feature/dirauth/dirauth_stub.c33
-rw-r--r--src/feature/dirauth/dirauth_sys.c26
-rw-r--r--src/feature/dirauth/dirauth_sys.h11
-rw-r--r--src/feature/dirauth/dirvote.c4
-rw-r--r--src/feature/relay/relay_stub.c20
-rw-r--r--src/feature/relay/relay_sys.c2
-rw-r--r--src/feature/relay/relay_sys.h10
-rw-r--r--src/lib/conf/confdecl.h23
-rw-r--r--src/lib/conf/conftypes.h15
-rw-r--r--src/lib/confmgt/confmgt.c3
-rw-r--r--src/lib/confmgt/structvar.c22
-rw-r--r--src/test/conf_examples/dirauth_2/expected1
-rw-r--r--src/test/conf_examples/dirauth_2/expected_log1
-rw-r--r--src/test/conf_examples/dirauth_2/expected_log_no_dirauth1
-rw-r--r--src/test/conf_examples/dirauth_2/expected_log_no_dirauth_relay1
-rw-r--r--src/test/conf_examples/dirauth_2/expected_no_dirauth0
-rw-r--r--src/test/conf_examples/dirauth_2/expected_no_dirauth_relay0
-rw-r--r--src/test/conf_examples/dirauth_2/torrc5
27 files changed, 247 insertions, 18 deletions
diff --git a/src/app/config/config.c b/src/app/config/config.c
index 5ea8cec6a6..680a7eeefa 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -337,7 +337,6 @@ static const config_var_t option_vars_[] = {
OBSOLETE("AuthDirRejectUnlisted"),
OBSOLETE("AuthDirListBadDirs"),
V(AuthDirListBadExits, BOOL, "0"),
- V(AuthDirMaxServersPerAddr, POSINT, "2"),
OBSOLETE("AuthDirMaxServersPerAuthAddr"),
V(AuthDirHasIPv6Connectivity, BOOL, "0"),
VAR("AuthoritativeDirectory", BOOL, AuthoritativeDir, "0"),
diff --git a/src/app/config/or_options_st.h b/src/app/config/or_options_st.h
index a3d63d9208..e63ae2510f 100644
--- a/src/app/config/or_options_st.h
+++ b/src/app/config/or_options_st.h
@@ -467,8 +467,6 @@ struct or_options_t {
int AuthDirListBadExits; /**< True iff we should list bad exits,
* and vote for all other exits as good. */
- int AuthDirMaxServersPerAddr; /**< Do not permit more than this
- * number of servers per IP address. */
int AuthDirHasIPv6Connectivity; /**< Boolean: are we on IPv6? */
int AuthDirPinKeys; /**< Boolean: Do we enforce key-pinning? */
diff --git a/src/app/main/subsystem_list.c b/src/app/main/subsystem_list.c
index a343207c1c..8b217715a5 100644
--- a/src/app/main/subsystem_list.c
+++ b/src/app/main/subsystem_list.c
@@ -66,13 +66,9 @@ const subsys_fns_t *tor_subsystems[] = {
&sys_mainloop,
&sys_or,
-#ifdef HAVE_MODULE_RELAY
&sys_relay,
-#endif
-#ifdef HAVE_MODULE_DIRAUTH
&sys_dirauth,
-#endif
};
const unsigned n_tor_subsystems = ARRAY_LENGTH(tor_subsystems);
diff --git a/src/core/include.am b/src/core/include.am
index 83230fb3ca..911932d46b 100644
--- a/src/core/include.am
+++ b/src/core/include.am
@@ -157,6 +157,11 @@ LIBTOR_APP_A_SOURCES = \
src/feature/stats/rephist.c \
src/feature/stats/predict_ports.c
+#
+# Sources that we only add for the real libtor_a, and not for testing.
+#
+LIBTOR_APP_A_STUB_SOURCES =
+
if BUILD_NT_SERVICES
LIBTOR_APP_A_SOURCES += src/app/main/ntmain.c
endif
@@ -199,13 +204,19 @@ MODULE_DIRAUTH_SOURCES = \
if BUILD_MODULE_RELAY
LIBTOR_APP_A_SOURCES += $(MODULE_RELAY_SOURCES)
+else
+LIBTOR_APP_A_STUB_SOURCES += src/feature/relay/relay_stub.c
endif
if BUILD_MODULE_DIRAUTH
LIBTOR_APP_A_SOURCES += $(MODULE_DIRAUTH_SOURCES)
+else
+LIBTOR_APP_A_STUB_SOURCES += src/feature/dirauth/dirauth_stub.c
endif
-src_core_libtor_app_a_SOURCES = $(LIBTOR_APP_A_SOURCES)
+src_core_libtor_app_a_SOURCES = \
+ $(LIBTOR_APP_A_SOURCES) \
+ $(LIBTOR_APP_A_STUB_SOURCES)
if UNITTESTS_ENABLED
# Add the sources of the modules that are needed for tests to work here.
@@ -344,6 +355,8 @@ noinst_HEADERS += \
src/feature/dirauth/bridgeauth.h \
src/feature/dirauth/bwauth.h \
src/feature/dirauth/dirauth_config.h \
+ src/feature/dirauth/dirauth_options.inc \
+ src/feature/dirauth/dirauth_options_st.h \
src/feature/dirauth/dirauth_periodic.h \
src/feature/dirauth/dirauth_sys.h \
src/feature/dirauth/dircollate.h \
diff --git a/src/feature/dirauth/.may_include b/src/feature/dirauth/.may_include
index 424c745c12..a9bb274699 100644
--- a/src/feature/dirauth/.may_include
+++ b/src/feature/dirauth/.may_include
@@ -1 +1,2 @@
*.h
+feature/dirauth/*.inc
diff --git a/src/feature/dirauth/dirauth_config.c b/src/feature/dirauth/dirauth_config.c
index 552f851461..b7e160c241 100644
--- a/src/feature/dirauth/dirauth_config.c
+++ b/src/feature/dirauth/dirauth_config.c
@@ -15,6 +15,7 @@
#include "lib/encoding/confline.h"
#include "lib/confmgt/confmgt.h"
+#include "lib/conf/confdecl.h"
/* Required for dirinfo_type_t in or_options_t */
#include "core/or/or.h"
@@ -28,6 +29,7 @@
#include "feature/dirauth/dirauth_periodic.h"
#include "feature/dirauth/dirvote.h"
#include "feature/dirauth/guardfraction.h"
+#include "feature/dirauth/dirauth_options_st.h"
/* Copied from config.c, we will refactor later in 29211. */
#define REJECT(arg) \
@@ -438,3 +440,23 @@ options_act_dirauth_stats(const or_options_t *old_options,
return 0;
}
+
+/* Declare the options field table for dirauth_options */
+#define CONF_CONTEXT TABLE
+#include "feature/dirauth/dirauth_options.inc"
+#undef CONF_CONTEXT
+
+/** Magic number for dirauth_options_t. */
+#define DIRAUTH_OPTIONS_MAGIC 0x41757448
+
+/**
+ * Declare the configuration options for the dirauth module.
+ **/
+const config_format_t dirauth_options_fmt = {
+ .size = sizeof(dirauth_options_t),
+ .magic = { "dirauth_options_t",
+ DIRAUTH_OPTIONS_MAGIC,
+ offsetof(dirauth_options_t, magic) },
+ .vars = dirauth_options_t_vars,
+};
+
diff --git a/src/feature/dirauth/dirauth_config.h b/src/feature/dirauth/dirauth_config.h
index b494ca685e..d21fb69d1e 100644
--- a/src/feature/dirauth/dirauth_config.h
+++ b/src/feature/dirauth/dirauth_config.h
@@ -39,6 +39,8 @@ int options_act_dirauth_mtbf(const struct or_options_t *old_options);
int options_act_dirauth_stats(const struct or_options_t *old_options,
bool *print_notice_out);
+extern const struct config_format_t dirauth_options_fmt;
+
#else /* !defined(HAVE_MODULE_DIRAUTH) */
/** When tor is compiled with the dirauth module disabled, it can't be
diff --git a/src/feature/dirauth/dirauth_options.inc b/src/feature/dirauth/dirauth_options.inc
new file mode 100644
index 0000000000..6b66f1e289
--- /dev/null
+++ b/src/feature/dirauth/dirauth_options.inc
@@ -0,0 +1,18 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * @file dirauth_options.inc
+ * @brief Declare configuration options for the crypto_ops module.
+ **/
+
+/** Holds configuration about our directory authority options. */
+BEGIN_CONF_STRUCT(dirauth_options_t)
+
+/** Do not permit more than this number of servers per IP address. */
+CONF_VAR(AuthDirMaxServersPerAddr, POSINT, 0, "2")
+
+END_CONF_STRUCT(dirauth_options_t)
diff --git a/src/feature/dirauth/dirauth_options_st.h b/src/feature/dirauth/dirauth_options_st.h
new file mode 100644
index 0000000000..93b9cb45bc
--- /dev/null
+++ b/src/feature/dirauth/dirauth_options_st.h
@@ -0,0 +1,22 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * @file dirauth_options_st.h
+ * @brief Structure dirauth_options_t to hold directory authority options.
+ **/
+
+#ifndef TOR_FEATURE_DIRAUTH_DIRAUTH_OPTIONS_ST_H
+#define TOR_FEATURE_DIRAUTH_DIRAUTH_OPTIONS_ST_H
+
+#include "lib/conf/confdecl.h"
+#define CONF_CONTEXT STRUCT
+#include "feature/dirauth/dirauth_options.inc"
+#undef CONF_CONTEXT
+
+typedef struct dirauth_options_t dirauth_options_t;
+
+#endif /* !defined(TOR_FEATURE_DIRAUTH_DIRAUTH_OPTIONS_ST_H) */
diff --git a/src/feature/dirauth/dirauth_stub.c b/src/feature/dirauth/dirauth_stub.c
new file mode 100644
index 0000000000..d902d56d2b
--- /dev/null
+++ b/src/feature/dirauth/dirauth_stub.c
@@ -0,0 +1,33 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * @file dirauth_stub.c
+ * @brief Stub declarations for use when dirauth module is disabled.
+ **/
+
+#include "orconfig.h"
+#include "feature/dirauth/dirauth_sys.h"
+#include "lib/conf/conftypes.h"
+#include "lib/conf/confdecl.h"
+#include "lib/subsys/subsys.h"
+
+/* Declare the options field table for dirauth_options */
+#define CONF_CONTEXT STUB_TABLE
+#include "feature/dirauth/dirauth_options.inc"
+#undef CONF_CONTEXT
+
+static const config_format_t dirauth_options_stub_fmt = {
+ .vars = dirauth_options_t_vars,
+};
+
+const struct subsys_fns_t sys_dirauth = {
+ .name = "dirauth",
+ .supported = false,
+ .level = DIRAUTH_SUBSYS_LEVEL,
+
+ .options_format = &dirauth_options_stub_fmt
+};
diff --git a/src/feature/dirauth/dirauth_sys.c b/src/feature/dirauth/dirauth_sys.c
index 090e9129f2..6ec25681e7 100644
--- a/src/feature/dirauth/dirauth_sys.c
+++ b/src/feature/dirauth/dirauth_sys.c
@@ -17,9 +17,14 @@
#include "feature/dirauth/dirauth_periodic.h"
#include "feature/dirauth/keypin.h"
#include "feature/dirauth/process_descs.h"
+#include "feature/dirauth/dirauth_config.h"
+
+#include "feature/dirauth/dirauth_options_st.h"
#include "lib/subsys/subsys.h"
+static const dirauth_options_t *global_dirauth_options;
+
static int
subsys_dirauth_initialize(void)
{
@@ -34,12 +39,31 @@ subsys_dirauth_shutdown(void)
dirvote_free_all();
dirserv_clear_measured_bw_cache();
keypin_close_journal();
+ global_dirauth_options = NULL;
+}
+
+const dirauth_options_t *
+dirauth_get_options(void)
+{
+ tor_assert(global_dirauth_options);
+ return global_dirauth_options;
+}
+
+static int
+dirauth_set_options(void *arg)
+{
+ dirauth_options_t *opts = arg;
+ global_dirauth_options = opts;
+ return 0;
}
const struct subsys_fns_t sys_dirauth = {
.name = "dirauth",
.supported = true,
- .level = 70,
+ .level = DIRAUTH_SUBSYS_LEVEL,
.initialize = subsys_dirauth_initialize,
.shutdown = subsys_dirauth_shutdown,
+
+ .options_format = &dirauth_options_fmt,
+ .set_options = dirauth_set_options,
};
diff --git a/src/feature/dirauth/dirauth_sys.h b/src/feature/dirauth/dirauth_sys.h
index 86c8d8ba3e..6f116855df 100644
--- a/src/feature/dirauth/dirauth_sys.h
+++ b/src/feature/dirauth/dirauth_sys.h
@@ -12,10 +12,17 @@
#ifndef DIRAUTH_SYS_H
#define DIRAUTH_SYS_H
-#ifdef HAVE_MODULE_DIRAUTH
+struct dirauth_options_t;
+const struct dirauth_options_t *dirauth_get_options(void);
extern const struct subsys_fns_t sys_dirauth;
-#endif
+/**
+ * Subsystem level for the directory-authority system.
+ *
+ * Defined here so that it can be shared between the real and stub
+ * definitions.
+ **/
+#define DIRAUTH_SUBSYS_LEVEL 70
#endif /* !defined(DIRAUTH_SYS_H) */
diff --git a/src/feature/dirauth/dirvote.c b/src/feature/dirauth/dirvote.c
index 043bbfc227..13003bf639 100644
--- a/src/feature/dirauth/dirvote.c
+++ b/src/feature/dirauth/dirvote.c
@@ -41,10 +41,12 @@
#include "feature/dirauth/dirvote.h"
#include "feature/dirauth/authmode.h"
#include "feature/dirauth/shared_random_state.h"
+#include "feature/dirauth/dirauth_sys.h"
#include "feature/nodelist/authority_cert_st.h"
#include "feature/dircache/cached_dir_st.h"
#include "feature/dirclient/dir_server_st.h"
+#include "feature/dirauth/dirauth_options_st.h"
#include "feature/nodelist/document_signature_st.h"
#include "feature/nodelist/microdesc_st.h"
#include "feature/nodelist/networkstatus_st.h"
@@ -4228,7 +4230,7 @@ compare_routerinfo_by_ip_and_bw_(const void **a, const void **b)
static digestmap_t *
get_possible_sybil_list(const smartlist_t *routers)
{
- const or_options_t *options = get_options();
+ const dirauth_options_t *options = dirauth_get_options();
digestmap_t *omit_as_sybil;
smartlist_t *routers_by_ip = smartlist_new();
uint32_t last_addr;
diff --git a/src/feature/relay/relay_stub.c b/src/feature/relay/relay_stub.c
new file mode 100644
index 0000000000..36daaa7bd7
--- /dev/null
+++ b/src/feature/relay/relay_stub.c
@@ -0,0 +1,20 @@
+/* Copyright (c) 2001 Matej Pfajfar.
+ * Copyright (c) 2001-2004, Roger Dingledine.
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * @file relay_stub.c
+ * @brief Stub declarations for use when relay module is disabled.
+ **/
+
+#include "orconfig.h"
+#include "feature/relay/relay_sys.h"
+#include "lib/subsys/subsys.h"
+
+const struct subsys_fns_t sys_relay = {
+ .name = "relay",
+ .supported = false,
+ .level = RELAY_SUBSYS_LEVEL,
+};
diff --git a/src/feature/relay/relay_sys.c b/src/feature/relay/relay_sys.c
index 106e88b2a5..dfddff27f2 100644
--- a/src/feature/relay/relay_sys.c
+++ b/src/feature/relay/relay_sys.c
@@ -42,7 +42,7 @@ subsys_relay_shutdown(void)
const struct subsys_fns_t sys_relay = {
.name = "relay",
.supported = true,
- .level = 50,
+ .level = RELAY_SUBSYS_LEVEL,
.initialize = subsys_relay_initialize,
.shutdown = subsys_relay_shutdown,
};
diff --git a/src/feature/relay/relay_sys.h b/src/feature/relay/relay_sys.h
index aa387369b5..ba3b5ccf4e 100644
--- a/src/feature/relay/relay_sys.h
+++ b/src/feature/relay/relay_sys.h
@@ -12,10 +12,14 @@
#ifndef TOR_FEATURE_RELAY_RELAY_SYS_H
#define TOR_FEATURE_RELAY_RELAY_SYS_H
-#ifdef HAVE_MODULE_RELAY
-
extern const struct subsys_fns_t sys_relay;
-#endif
+/**
+ * Subsystem level for the relay system.
+ *
+ * Defined here so that it can be shared between the real and stub
+ * definitions.
+ **/
+#define RELAY_SUBSYS_LEVEL 50
#endif /* !defined(TOR_FEATURE_RELAY_RELAY_SYS_H) */
diff --git a/src/lib/conf/confdecl.h b/src/lib/conf/confdecl.h
index 294a1e7173..723aea1878 100644
--- a/src/lib/conf/confdecl.h
+++ b/src/lib/conf/confdecl.h
@@ -51,6 +51,7 @@
#undef CONF_CONTEXT
#include "lib/cc/tokpaste.h"
+#include "lib/cc/torint.h"
/**
* Begin the definition of a configuration object called `name`.
@@ -134,6 +135,28 @@
.initvalue = initval \
},
/**@}*/
+
+/* @defgroup STUB_TABLE_MACROS Internal macros: stub table declarations,
+ * for use when a module is disabled.
+ * Implementation helpers: the regular confdecl macros expand to these
+ * when CONF_CONTEXT is defined to LL_TABLE. Don't use them directly.
+ * @{*/
+#define BEGIN_CONF_STRUCT__STUB_TABLE(structname) \
+ static const config_var_t structname##_vars[] = {
+#define END_CONF_STRUCT__STUB_TABLE(structname) \
+ { .member = { .name = NULL } } \
+ };
+#define CONF_VAR__STUB_TABLE(varname, vartype, varflags, initval) \
+ { \
+ .member = \
+ { .name = #varname, \
+ .type = CONFIG_TYPE_IGNORE, \
+ .offset = -1, \
+ }, \
+ .flags = CFLG_GROUP_DISABLED, \
+ },
+/**@}*/
+
#endif /* !defined(COCCI) */
/** Type aliases for the "commonly used" configuration types.
diff --git a/src/lib/conf/conftypes.h b/src/lib/conf/conftypes.h
index 19ea997316..52f9fceb20 100644
--- a/src/lib/conf/conftypes.h
+++ b/src/lib/conf/conftypes.h
@@ -131,6 +131,9 @@ typedef struct struct_member_t {
*
* These 'magic numbers' are 32-bit values used to tag objects to make sure
* that they have the correct type.
+ *
+ * If all fields in this structure are zero or 0, the magic-number check is
+ * not performed.
*/
typedef struct struct_magic_decl_t {
/** The name of the structure */
@@ -199,6 +202,11 @@ typedef struct struct_magic_decl_t {
* whenever the user tries to use it.
**/
#define CFLG_WARN_OBSOLETE (1u<<7)
+/**
+ * Flag to indicate that we should warn that an option applies only to
+ * a disabled module, whenever the user tries to use it.
+ **/
+#define CFLG_WARN_DISABLED (1u<<8)
/**
* A group of flags that should be set on all obsolete options and types.
@@ -207,6 +215,13 @@ typedef struct struct_magic_decl_t {
(CFLG_NOCOPY|CFLG_NOCMP|CFLG_NODUMP|CFLG_NOSET|CFLG_NOLIST|\
CFLG_WARN_OBSOLETE)
+/**
+ * A group of fflags that should be set on all disabled options.
+ **/
+#define CFLG_GROUP_DISABLED \
+ (CFLG_NOCOPY|CFLG_NOCMP|CFLG_NODUMP|CFLG_NOSET|CFLG_NOLIST|\
+ CFLG_WARN_DISABLED)
+
/** A variable allowed in the configuration file or on the command line. */
typedef struct config_var_t {
struct_member_t member; /** A struct member corresponding to this
diff --git a/src/lib/confmgt/confmgt.c b/src/lib/confmgt/confmgt.c
index c72efa847c..eaa4468d55 100644
--- a/src/lib/confmgt/confmgt.c
+++ b/src/lib/confmgt/confmgt.c
@@ -660,6 +660,9 @@ config_assign_value(const config_mgr_t *mgr, void *options,
if (config_var_has_flag(var->cvar, CFLG_WARN_OBSOLETE)) {
log_warn(LD_GENERAL, "Skipping obsolete configuration option \"%s\".",
var->cvar->member.name);
+ } else if (config_var_has_flag(var->cvar, CFLG_WARN_DISABLED)) {
+ log_warn(LD_GENERAL, "This copy of Tor was built without support for "
+ "the option \"%s\". Skipping.", var->cvar->member.name);
}
return struct_var_kvassign(object, c, msg, &var->cvar->member);
diff --git a/src/lib/confmgt/structvar.c b/src/lib/confmgt/structvar.c
index de678d18c8..a2411477d6 100644
--- a/src/lib/confmgt/structvar.c
+++ b/src/lib/confmgt/structvar.c
@@ -30,13 +30,28 @@
#include <stddef.h>
/**
+ * Return true iff all fields on <b>decl</b> are NULL or 0, indicating that
+ * there is no object or no magic number to check.
+ **/
+static inline bool
+magic_is_null(const struct_magic_decl_t *decl)
+{
+ return decl->typename == NULL &&
+ decl->magic_offset == 0 &&
+ decl->magic_val == 0;
+}
+
+/**
* Set the 'magic number' on <b>object</b> to correspond to decl.
**/
void
struct_set_magic(void *object, const struct_magic_decl_t *decl)
{
- tor_assert(object);
tor_assert(decl);
+ if (magic_is_null(decl))
+ return;
+
+ tor_assert(object);
uint32_t *ptr = STRUCT_VAR_P(object, decl->magic_offset);
*ptr = decl->magic_val;
}
@@ -47,8 +62,11 @@ struct_set_magic(void *object, const struct_magic_decl_t *decl)
void
struct_check_magic(const void *object, const struct_magic_decl_t *decl)
{
- tor_assert(object);
tor_assert(decl);
+ if (magic_is_null(decl))
+ return;
+
+ tor_assert(object);
const uint32_t *ptr = STRUCT_VAR_P(object, decl->magic_offset);
tor_assertf(*ptr == decl->magic_val,
diff --git a/src/test/conf_examples/dirauth_2/expected b/src/test/conf_examples/dirauth_2/expected
new file mode 100644
index 0000000000..19ab024ed3
--- /dev/null
+++ b/src/test/conf_examples/dirauth_2/expected
@@ -0,0 +1 @@
+AuthDirMaxServersPerAddr 8
diff --git a/src/test/conf_examples/dirauth_2/expected_log b/src/test/conf_examples/dirauth_2/expected_log
new file mode 100644
index 0000000000..88611fee9d
--- /dev/null
+++ b/src/test/conf_examples/dirauth_2/expected_log
@@ -0,0 +1 @@
+Read configuration file
diff --git a/src/test/conf_examples/dirauth_2/expected_log_no_dirauth b/src/test/conf_examples/dirauth_2/expected_log_no_dirauth
new file mode 100644
index 0000000000..01110c5d8c
--- /dev/null
+++ b/src/test/conf_examples/dirauth_2/expected_log_no_dirauth
@@ -0,0 +1 @@
+This copy of Tor was built without support for the option "AuthDirMaxServersPerAddr". Skipping. \ No newline at end of file
diff --git a/src/test/conf_examples/dirauth_2/expected_log_no_dirauth_relay b/src/test/conf_examples/dirauth_2/expected_log_no_dirauth_relay
new file mode 100644
index 0000000000..01110c5d8c
--- /dev/null
+++ b/src/test/conf_examples/dirauth_2/expected_log_no_dirauth_relay
@@ -0,0 +1 @@
+This copy of Tor was built without support for the option "AuthDirMaxServersPerAddr". Skipping. \ No newline at end of file
diff --git a/src/test/conf_examples/dirauth_2/expected_no_dirauth b/src/test/conf_examples/dirauth_2/expected_no_dirauth
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/test/conf_examples/dirauth_2/expected_no_dirauth
diff --git a/src/test/conf_examples/dirauth_2/expected_no_dirauth_relay b/src/test/conf_examples/dirauth_2/expected_no_dirauth_relay
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/test/conf_examples/dirauth_2/expected_no_dirauth_relay
diff --git a/src/test/conf_examples/dirauth_2/torrc b/src/test/conf_examples/dirauth_2/torrc
new file mode 100644
index 0000000000..bd1cdbc8b9
--- /dev/null
+++ b/src/test/conf_examples/dirauth_2/torrc
@@ -0,0 +1,5 @@
+#
+# This will get accepted if the module is enabled, and ignored if the module
+# is disabled.
+#
+AuthDirMaxServersPerAddr 8