35 #include "feature/hs/hs_opts_st.h"
39 #define CONF_CONTEXT TABLE
40 #include "feature/hs/hs_options.inc"
44 #define HS_OPTS_MAGIC 0x6f6e796e
48 .magic = {
"hs_opts_t",
51 .vars = hs_opts_t_vars,
86 #define hs_opts_free(opts) \
87 config_free(get_hs_opts_mgr(), (opts))
143 log_warn(
LD_REND,
"Another hidden service is already configured "
149 } SMARTLIST_FOREACH_END(s);
161 if (i < low || i > high) {
165 log_warn(
LD_CONFIG,
"%s must be between %d and %d, not %d.",
177 #define CHECK_OOB(opts, name, low, high) \
178 check_value_oob((opts)->name, #name, (low), (high))
193 if (! strcasecmp(value,
"haproxy")) {
196 }
else if (! strcasecmp(value,
"none")) {
200 log_warn(
LD_CONFIG,
"%s must be 'haproxy' or 'none'.", key);
244 const char **optlist;
252 const char *opts_exclude_v3[] = {
253 "HiddenServiceAuthorizeClient",
270 if (optlist == NULL) {
274 for (
int i = 0; optlist[i]; i++) {
275 const char *opt = optlist[i];
276 for (line = line_; line; line = line->next) {
284 if (!strcasecmp(line->key, opt)) {
285 log_warn(
LD_CONFIG,
"Hidden service option %s is incompatible with "
286 "version %" PRIu32
" of service in %s",
309 if (!config->
ports || smartlist_len(config->
ports) == 0) {
310 log_warn(
LD_CONFIG,
"Hidden service (%s) with no ports configured.",
317 (config->intro_dos_burst_per_sec < config->intro_dos_rate_per_sec)) {
318 log_warn(
LD_CONFIG,
"Hidden service DoS defenses burst (%" PRIu32
") can "
319 "not be smaller than the rate value (%" PRIu32
").",
320 config->intro_dos_burst_per_sec, config->intro_dos_rate_per_sec);
343 if (
CHECK_OOB(hs_opts, HiddenServiceNumIntroductionPoints,
345 HS_CONFIG_V3_MAX_INTRO_POINTS)) {
351 if (hs_opts->HiddenServiceExportCircuitID) {
355 hs_opts->HiddenServiceExportCircuitID,
364 hs_opts->HiddenServiceEnableIntroDoSDefense;
367 if (
CHECK_OOB(hs_opts, HiddenServiceEnableIntroDoSRatePerSec,
368 HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_MIN,
369 HS_CONFIG_V3_DOS_DEFENSE_RATE_PER_SEC_MAX)) {
372 config->intro_dos_rate_per_sec =
373 hs_opts->HiddenServiceEnableIntroDoSRatePerSec;
374 log_info(
LD_REND,
"Service INTRO2 DoS defenses rate set to: %" PRIu32,
375 config->intro_dos_rate_per_sec);
377 if (
CHECK_OOB(hs_opts, HiddenServiceEnableIntroDoSBurstPerSec,
378 HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_MIN,
379 HS_CONFIG_V3_DOS_DEFENSE_BURST_PER_SEC_MAX)) {
382 config->intro_dos_burst_per_sec =
383 hs_opts->HiddenServiceEnableIntroDoSBurstPerSec;
384 log_info(
LD_REND,
"Service INTRO2 DoS defenses burst set to: %" PRIu32,
385 config->intro_dos_burst_per_sec);
388 if (hs_opts->HiddenServiceOnionBalanceInstance) {
432 config = &service->
config;
437 log_info(
LD_CONFIG,
"%s=%s. Configuring...",
441 if (hs_opts->HiddenServiceVersion == -1) {
443 }
else if (hs_opts->HiddenServiceVersion == 2) {
444 log_warn(
LD_CONFIG,
"Onion services version 2 are obsolete. Please see "
445 "https://blog.torproject.org/v2-deprecation-timeline "
446 "for more details and for instructions on how to "
447 "transition to version 3.");
449 }
else if (
CHECK_OOB(hs_opts, HiddenServiceVersion,
454 config->
version = hs_opts->HiddenServiceVersion;
458 for (
const config_line_t *portline = hs_opts->HiddenServicePort;
459 portline; portline = portline->next) {
460 char *err_msg = NULL;
473 log_info(
LD_CONFIG,
"HiddenServicePort=%s for %s",
484 if (
CHECK_OOB(hs_opts, HiddenServiceMaxStreams,
485 0, HS_CONFIG_MAX_STREAMS_PER_RDV_CIRCUIT)) {
492 hs_opts->HiddenServiceMaxStreamsCloseCircuit;
496 if (hs_service_non_anonymous_mode_enabled(options)) {
531 log_warn(
LD_REND,
"Can't parse configuration for onion service: %s", msg);
534 tor_assert_nonfatal(msg == NULL);
538 log_warn(
LD_REND,
"Bad configuration for onion service: %s", msg);
541 tor_assert_nonfatal(msg == NULL);
632 log_warn(
LD_CONFIG,
"%s with no preceding %s directive",
645 config_free_lines(section);
647 config_free_lines(remaining);
656 if (!validate_only) {
673 smartlist_free(new_service_list);
Macros for generating a configuration struct from a list of its individual fields.
config_line_t * config_lines_partition(config_line_t *inp, const char *header)
config_line_t * config_lines_dup(const config_line_t *inp)
void config_init(const config_mgr_t *mgr, void *options)
void config_mgr_freeze(config_mgr_t *mgr)
void * config_new(const config_mgr_t *mgr)
config_mgr_t * config_mgr_new(const config_format_t *toplevel_fmt)
validation_status_t config_validate(const config_mgr_t *mgr, const void *old_options, void *options, char **msg_out)
int config_assign(const config_mgr_t *mgr, void *options, config_line_t *list, unsigned config_assign_flags, char **msg)
const char * escaped(const char *s)
int hs_config_client_authorization(const or_options_t *options, int validate_only)
Header file containing client data for the HS subsystem.
int hs_check_service_private_dir(const char *username, const char *path, unsigned int dir_group_readable, unsigned int create)
hs_port_config_t * hs_parse_port_config(const char *string, const char *sep, char **err_msg_out)
Header file containing common data for the whole HS subsystem.
#define NUM_INTRO_POINTS_DEFAULT
int hs_config_client_auth_all(const or_options_t *options, int validate_only)
static int config_service_v3(const hs_opts_t *hs_opts, hs_service_config_t *config)
static int config_generic_service(const hs_opts_t *hs_opts, const or_options_t *options, hs_service_t *service)
void hs_config_free_all(void)
#define CHECK_OOB(opts, name, low, high)
int hs_config_service_all(const or_options_t *options, int validate_only)
static int config_learn_service_version(hs_service_t *service)
static bool check_value_oob(int i, const char *name, int low, int high)
static hs_circuit_id_protocol_t helper_parse_circuit_id_protocol(const char *key, const char *value, int *ok)
static void stage_services(smartlist_t *service_list)
#define hs_opts_free(opts)
static const char SECTION_HEADER[]
static const config_mgr_t * get_hs_opts_mgr(void)
static config_mgr_t * hs_opts_mgr
static int config_service(config_line_t *line, const or_options_t *options, smartlist_t *service_list)
static hs_opts_t * hs_opts_new(void)
static int config_has_invalid_options(const config_line_t *line_, const hs_service_t *service)
static int service_is_duplicate_in_list(const smartlist_t *service_list, const hs_service_t *service)
static int config_validate_service(const hs_service_config_t *config)
Header file containing configuration ABI/API for the HS subsystem.
int hs_ob_parse_config_file(hs_service_config_t *config)
Header file for the specific code for onion balance.
void hs_service_stage_services(const smartlist_t *service_list)
hs_service_t * hs_service_new(const or_options_t *options)
int hs_service_get_version_from_key(const hs_service_t *service)
Header file containing service data for the HS subsystem.
@ HS_CIRCUIT_ID_PROTOCOL_NONE
@ HS_CIRCUIT_ID_PROTOCOL_HAPROXY
#define hs_service_free(s)
The or_options_t structure, which represents Tor's configuration.
smartlist_t * smartlist_new(void)
void smartlist_add(smartlist_t *sl, void *element)
#define SMARTLIST_FOREACH_BEGIN(sl, type, var)
#define SMARTLIST_FOREACH(sl, type, var, cmd)
hs_circuit_id_protocol_t circuit_id_protocol
uint64_t max_streams_per_rdv_circuit
unsigned int is_single_onion
unsigned int dir_group_readable
unsigned int hs_version_explicitly_set
unsigned int max_streams_close_circuit
unsigned int is_ephemeral
unsigned int has_dos_defense_enabled
unsigned int num_intro_points
unsigned int allow_unknown_ports
hs_service_config_t config
struct config_line_t * RendConfigLines
#define tor_assert_nonfatal_unreached()