Tor  0.4.8.0-alpha-dev
hs_config.c
Go to the documentation of this file.
1 /* Copyright (c) 2017-2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
3 
4 /**
5  * \file hs_config.c
6  * \brief Implement hidden service configuration subsystem.
7  *
8  * \details
9  *
10  * This file has basically one main entry point: hs_config_service_all(). It
11  * takes the torrc options and configure hidden service from it. In validate
12  * mode, nothing is added to the global service list or keys are not generated
13  * nor loaded.
14  *
15  * A service is configured in two steps. It is first created using the tor
16  * options and then put in a staging list. It will stay there until
17  * hs_service_load_all_keys() is called. That function is responsible to
18  * load/generate the keys for the service in the staging list and if
19  * successful, transferred the service to the main global service list where
20  * at that point it is ready to be used.
21  *
22  * Configuration functions are per-version and there is a main generic one for
23  * every option that is common to all version (config_generic_service).
24  **/
25 
26 #include "feature/hs/hs_common.h"
27 #include "feature/hs/hs_config.h"
28 #include "feature/hs/hs_client.h"
29 #include "feature/hs/hs_ob.h"
30 #include "feature/hs/hs_service.h"
31 #include "lib/encoding/confline.h"
32 #include "lib/conf/confdecl.h"
33 #include "lib/confmgt/confmgt.h"
34 
35 #include "feature/hs/hs_opts_st.h"
37 
38 /* Declare the table mapping hs options to hs_opts_t */
39 #define CONF_CONTEXT TABLE
40 #include "feature/hs/hs_options.inc"
41 #undef CONF_CONTEXT
42 
43 /** Magic number for hs_opts_t. */
44 #define HS_OPTS_MAGIC 0x6f6e796e
45 
46 static const config_format_t hs_opts_fmt = {
47  .size = sizeof(hs_opts_t),
48  .magic = { "hs_opts_t",
50  offsetof(hs_opts_t, magic) },
51  .vars = hs_opts_t_vars,
52 };
53 
54 /** Global configuration manager to handle HS sections*/
55 static config_mgr_t *hs_opts_mgr = NULL;
56 
57 /**
58  * Return a configuration manager for the hs_opts_t configuration type.
59  **/
60 static const config_mgr_t *
62 {
63  if (PREDICT_UNLIKELY(hs_opts_mgr == NULL)) {
64  hs_opts_mgr = config_mgr_new(&hs_opts_fmt);
66  }
67  return hs_opts_mgr;
68 }
69 
70 /**
71  * Allocate, initialize, and return a new hs_opts_t.
72  **/
73 static hs_opts_t *
75 {
76  const config_mgr_t *mgr = get_hs_opts_mgr();
77  hs_opts_t *r = config_new(mgr);
78  tor_assert(r);
79  config_init(mgr, r);
80  return r;
81 }
82 
83 /**
84  * Free an hs_opts_t.
85  **/
86 #define hs_opts_free(opts) \
87  config_free(get_hs_opts_mgr(), (opts))
88 
89 /** Using the given list of services, stage them into our global state. Every
90  * service version are handled. This function can remove entries in the given
91  * service_list.
92  *
93  * Staging a service means that we take all services in service_list and we
94  * put them in the staging list (global) which acts as a temporary list that
95  * is used by the service loading key process. In other words, staging a
96  * service puts it in a list to be considered when loading the keys and then
97  * moved to the main global list. */
98 static void
100 {
101  tor_assert(service_list);
102 
103  /* This is >= v3 specific. Using the newly configured service list, stage
104  * them into our global state. Every object ownership is lost after. */
105  hs_service_stage_services(service_list);
106 }
107 
108 /** Validate the given service against all service in the given list. If the
109  * service is ephemeral, this function ignores it. Services with the same
110  * directory path aren't allowed and will return an error. If a duplicate is
111  * found, 1 is returned else 0 if none found. */
112 static int
114  const hs_service_t *service)
115 {
116  int ret = 0;
117 
118  tor_assert(service_list);
119  tor_assert(service);
120 
121  /* Ephemeral service don't have a directory configured so no need to check
122  * for a service in the list having the same path. */
123  if (service->config.is_ephemeral) {
124  goto end;
125  }
126 
127  /* XXX: Validate if we have any service that has the given service dir path.
128  * This has two problems:
129  *
130  * a) It's O(n^2)
131  *
132  * b) We only compare directory paths as strings, so we can't
133  * detect two distinct paths that specify the same directory
134  * (which can arise from symlinks, case-insensitivity, bind
135  * mounts, etc.).
136  *
137  * It also can't detect that two separate Tor instances are trying
138  * to use the same HiddenServiceDir; for that, we would need a
139  * lock file. But this is enough to detect a simple mistake that
140  * at least one person has actually made. */
141  SMARTLIST_FOREACH_BEGIN(service_list, const hs_service_t *, s) {
142  if (!strcmp(s->config.directory_path, service->config.directory_path)) {
143  log_warn(LD_REND, "Another hidden service is already configured "
144  "for directory %s",
145  escaped(service->config.directory_path));
146  ret = 1;
147  goto end;
148  }
149  } SMARTLIST_FOREACH_END(s);
150 
151  end:
152  return ret;
153 }
154 
155 /** Check whether an integer <b>i</b> is out of bounds (not between <b>low</b>
156  * and <b>high</b> incusive). If it is, then log a warning about the option
157  * <b>name</b>, and return true. Otherwise return false. */
158 static bool
159 check_value_oob(int i, const char *name, int low, int high)
160 {
161  if (i < low || i > high) {
162  if (low == high) {
163  log_warn(LD_CONFIG, "%s must be %d, not %d.", name, low, i);
164  } else {
165  log_warn(LD_CONFIG, "%s must be between %d and %d, not %d.",
166  name, low, high, i);
167  }
168  return true;
169  }
170  return false;
171 }
172 
173 /**
174  * Helper: check whether the integer value called <b>name</b> in <b>opts</b>
175  * is out-of-bounds.
176  **/
177 #define CHECK_OOB(opts, name, low, high) \
178  check_value_oob((opts)->name, #name, (low), (high))
179 
180 /** Helper function: Given a configuration option and its value, parse the
181  * value as a hs_circuit_id_protocol_t. On success, ok is set to 1 and ret is
182  * the parse value. On error, ok is set to 0 and the "none"
183  * hs_circuit_id_protocol_t is returned. This function logs on error. */
185 helper_parse_circuit_id_protocol(const char *key, const char *value, int *ok)
186 {
187  tor_assert(value);
188  tor_assert(ok);
189 
191  *ok = 0;
192 
193  if (! strcasecmp(value, "haproxy")) {
194  *ok = 1;
196  } else if (! strcasecmp(value, "none")) {
197  *ok = 1;
199  } else {
200  log_warn(LD_CONFIG, "%s must be 'haproxy' or 'none'.", key);
201  goto err;
202  }
203 
204  err:
205  return ret;
206 }
207 
208 /** Return the service version by trying to learn it from the key on disk if
209  * any. If nothing is found, the current service configured version is
210  * returned. */
211 static int
213 {
214  int version;
215 
216  tor_assert(service);
217 
218  version = hs_service_get_version_from_key(service);
219  if (version < 0) {
220  version = service->config.version;
221  }
222 
223  return version;
224 }
225 
226 /**
227  * Header key indicating the start of a new hidden service configuration
228  * block.
229  **/
230 static const char SECTION_HEADER[] = "HiddenServiceDir";
231 
232 /** Return true iff the given options starting at line_ for a hidden service
233  * contains at least one invalid option. Each hidden service option don't
234  * apply to all versions so this function can find out. The line_ MUST start
235  * right after the HiddenServiceDir line of this service.
236  *
237  * This is mainly for usability so we can inform the user of any invalid
238  * option for the hidden service version instead of silently ignoring. */
239 static int
241  const hs_service_t *service)
242 {
243  int ret = 0;
244  const char **optlist;
245  const config_line_t *line;
246 
247  tor_assert(service);
249 
250  /* List of options that a v3 service doesn't support thus must exclude from
251  * its configuration. */
252  const char *opts_exclude_v3[] = {
253  "HiddenServiceAuthorizeClient",
254  NULL /* End marker. */
255  };
256 
257  /* Defining the size explicitly allows us to take advantage of the compiler
258  * which warns us if we ever bump the max version but forget to grow this
259  * array. The plus one is because we have a version 0 :). */
260  struct {
261  const char **list;
262  } exclude_lists[HS_VERSION_MAX + 1] = {
263  { NULL }, /* v0. */
264  { NULL }, /* v1. */
265  { NULL }, /* v2. */
266  { opts_exclude_v3 }, /* v3. */
267  };
268 
269  optlist = exclude_lists[service->config.version].list;
270  if (optlist == NULL) {
271  /* No exclude options to look at for this version. */
272  goto end;
273  }
274  for (int i = 0; optlist[i]; i++) {
275  const char *opt = optlist[i];
276  for (line = line_; line; line = line->next) {
277  if (!strcasecmp(line->key, SECTION_HEADER)) {
278  /* We just hit the next hidden service, stop right now.
279  * (This shouldn't be possible, now that we have partitioned the list
280  * into sections.) */
282  goto end;
283  }
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",
287  opt, service->config.version,
288  service->config.directory_path);
289  ret = 1;
290  /* Continue the loop so we can find all possible options. */
291  continue;
292  }
293  }
294  }
295  end:
296  return ret;
297 }
298 
299 /** Validate service configuration. This is used when loading the configuration
300  * and once we've setup a service object, it's config object is passed to this
301  * function for further validation. This does not validate service key
302  * material. Return 0 if valid else -1 if invalid. */
303 static int
305 {
306  tor_assert(config);
307 
308  /* Amount of ports validation. */
309  if (!config->ports || smartlist_len(config->ports) == 0) {
310  log_warn(LD_CONFIG, "Hidden service (%s) with no ports configured.",
311  escaped(config->directory_path));
312  goto invalid;
313  }
314 
315  /* DoS validation values. */
316  if (config->has_dos_defense_enabled &&
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);
321  goto invalid;
322  }
323 
324  /* Valid. */
325  return 0;
326  invalid:
327  return -1;
328 }
329 
330 /** Configuration function for a version 3 service. The given service
331  * object must be already allocated and passed through
332  * config_generic_service() prior to calling this function.
333  *
334  * Return 0 on success else a negative value. */
335 static int
337  hs_service_config_t *config)
338 {
339  tor_assert(config);
340  tor_assert(hs_opts);
341 
342  /* Number of introduction points. */
343  if (CHECK_OOB(hs_opts, HiddenServiceNumIntroductionPoints,
345  HS_CONFIG_V3_MAX_INTRO_POINTS)) {
346  goto err;
347  }
348  config->num_intro_points = hs_opts->HiddenServiceNumIntroductionPoints;
349 
350  /* Circuit ID export setting. */
351  if (hs_opts->HiddenServiceExportCircuitID) {
352  int ok;
353  config->circuit_id_protocol =
354  helper_parse_circuit_id_protocol("HiddenServcieExportCircuitID",
355  hs_opts->HiddenServiceExportCircuitID,
356  &ok);
357  if (!ok) {
358  goto err;
359  }
360  }
361 
362  /* Is the DoS defense enabled? */
363  config->has_dos_defense_enabled =
364  hs_opts->HiddenServiceEnableIntroDoSDefense;
365 
366  /* Rate for DoS defense */
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)) {
370  goto err;
371  }
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);
376 
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)) {
380  goto err;
381  }
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);
386 
387  /* Is this an onionbalance instance? */
388  if (hs_opts->HiddenServiceOnionBalanceInstance) {
389  /* Option is enabled, parse config file. */
390  if (! hs_ob_parse_config_file(config)) {
391  goto err;
392  }
393  }
394 
395  /* We do not load the key material for the service at this stage. This is
396  * done later once tor can confirm that it is in a running state. */
397 
398  /* We are about to return a fully configured service so do one last pass of
399  * validation at it. */
400  if (config_validate_service(config) < 0) {
401  goto err;
402  }
403 
404  return 0;
405  err:
406  return -1;
407 }
408 
409 /** Configure a service using the given options in hs_opts and options. This is
410  * called for any service regardless of its version which means that all
411  * directives in this function are generic to any service version. This
412  * function will also check the validity of the service directory path.
413  *
414  * The line_ must be pointing to the directive directly after a
415  * HiddenServiceDir. That way, when hitting the next HiddenServiceDir line or
416  * reaching the end of the list of lines, we know that we have to stop looking
417  * for more options.
418  *
419  * Return 0 on success else -1. */
420 static int
422  const or_options_t *options,
423  hs_service_t *service)
424 {
425  hs_service_config_t *config;
426 
427  tor_assert(hs_opts);
428  tor_assert(options);
429  tor_assert(service);
430 
431  /* Makes thing easier. */
432  config = &service->config;
433 
434  /* Directory where the service's keys are stored. */
435  tor_assert(hs_opts->HiddenServiceDir);
436  config->directory_path = tor_strdup(hs_opts->HiddenServiceDir);
437  log_info(LD_CONFIG, "%s=%s. Configuring...",
439 
440  /* Protocol version for the service. */
441  if (hs_opts->HiddenServiceVersion == -1) {
442  /* No value was set; stay with the default. */
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.");
448  goto err;
449  } else if (CHECK_OOB(hs_opts, HiddenServiceVersion,
451  goto err;
452  } else {
453  config->hs_version_explicitly_set = 1;
454  config->version = hs_opts->HiddenServiceVersion;
455  }
456 
457  /* Virtual port. */
458  for (const config_line_t *portline = hs_opts->HiddenServicePort;
459  portline; portline = portline->next) {
460  char *err_msg = NULL;
461  /* XXX: Can we rename this? */
462  hs_port_config_t *portcfg =
463  hs_parse_port_config(portline->value, " ", &err_msg);
464  if (!portcfg) {
465  if (err_msg) {
466  log_warn(LD_CONFIG, "%s", err_msg);
467  }
468  tor_free(err_msg);
469  goto err;
470  }
471  tor_assert(!err_msg);
472  smartlist_add(config->ports, portcfg);
473  log_info(LD_CONFIG, "HiddenServicePort=%s for %s",
474  portline->value, escaped(config->directory_path));
475  }
476 
477  /* Do we allow unknown ports? */
478  config->allow_unknown_ports = hs_opts->HiddenServiceAllowUnknownPorts;
479 
480  /* Directory group readable. */
481  config->dir_group_readable = hs_opts->HiddenServiceDirGroupReadable;
482 
483  /* Maximum streams per circuit. */
484  if (CHECK_OOB(hs_opts, HiddenServiceMaxStreams,
485  0, HS_CONFIG_MAX_STREAMS_PER_RDV_CIRCUIT)) {
486  goto err;
487  }
488  config->max_streams_per_rdv_circuit = hs_opts->HiddenServiceMaxStreams;
489 
490  /* Maximum amount of streams before we close the circuit. */
491  config->max_streams_close_circuit =
492  hs_opts->HiddenServiceMaxStreamsCloseCircuit;
493 
494  /* Check if we are configured in non anonymous mode meaning every service
495  * becomes a single onion service. */
496  if (hs_service_non_anonymous_mode_enabled(options)) {
497  config->is_single_onion = 1;
498  }
499 
500  /* Success */
501  return 0;
502  err:
503  return -1;
504 }
505 
506 /** Configure a service using the given line and options. This function will
507  * call the corresponding configuration function for a specific service
508  * version and validate the service against the other ones. On success, add
509  * the service to the given list and return 0. On error, nothing is added to
510  * the list and a negative value is returned. */
511 static int
513  smartlist_t *service_list)
514 {
515  int ret;
516  hs_service_t *service = NULL;
517  hs_opts_t *hs_opts = NULL;
518  char *msg = NULL;
519 
520  tor_assert(line);
521  tor_assert(options);
522  tor_assert(service_list);
523 
524  /* We have a new hidden service. */
525  service = hs_service_new(options);
526 
527  /* Try to validate and parse the configuration lines into 'hs_opts' */
528  hs_opts = hs_opts_new();
529  ret = config_assign(get_hs_opts_mgr(), hs_opts, line, 0, &msg);
530  if (ret < 0) {
531  log_warn(LD_REND, "Can't parse configuration for onion service: %s", msg);
532  goto err;
533  }
534  tor_assert_nonfatal(msg == NULL);
536  hs_opts, &msg);
537  if (vs < 0) {
538  log_warn(LD_REND, "Bad configuration for onion service: %s", msg);
539  goto err;
540  }
541  tor_assert_nonfatal(msg == NULL);
542 
543  /* We'll configure that service as a generic one and then pass it to a
544  * specific function according to the configured version number. */
545  if (config_generic_service(hs_opts, options, service) < 0) {
546  goto err;
547  }
548 
550 
551  /* If we're running with TestingTorNetwork enabled, we relax the permissions
552  * check on the hs directory. */
553  if (!options->TestingTorNetwork) {
554  /* Check permission on service directory that was just parsed. And this
555  * must be done regardless of the service version. Do not ask for the
556  * directory to be created, this is done when the keys are loaded because
557  * we could be in validation mode right now. */
558  if (hs_check_service_private_dir(options->User,
559  service->config.directory_path,
560  service->config.dir_group_readable,
561  0) < 0) {
562  goto err;
563  }
564  }
565 
566  /* We'll try to learn the service version here by loading the key(s) if
567  * present and we did not set HiddenServiceVersion. Depending on the key
568  * format, we can figure out the service version. */
569  if (!service->config.hs_version_explicitly_set) {
570  service->config.version = config_learn_service_version(service);
571  }
572 
573  /* We make sure that this set of options for a service are valid. */
574  if (config_has_invalid_options(line->next, service)) {
575  goto err;
576  }
577 
578  /* Different functions are in charge of specific options for a version. We
579  * start just after the service directory line so once we hit another
580  * directory line, the function knows that it has to stop parsing. */
581  switch (service->config.version) {
582  case HS_VERSION_THREE:
583  ret = config_service_v3(hs_opts, &service->config);
584  break;
585  default:
586  /* We do validate before if we support the parsed version. */
588  goto err;
589  }
590  if (ret < 0) {
591  goto err;
592  }
593 
594  /* We'll check if this service can be kept depending on the others
595  * configured previously. */
596  if (service_is_duplicate_in_list(service_list, service)) {
597  goto err;
598  }
599 
600  /* Passes, add it to the given list. */
601  smartlist_add(service_list, service);
602  hs_opts_free(hs_opts);
603 
604  return 0;
605 
606  err:
607  hs_service_free(service);
608  hs_opts_free(hs_opts);
609  tor_free(msg);
610  return -1;
611 }
612 
613 /** From a set of <b>options</b>, setup every hidden service found. Return 0 on
614  * success or -1 on failure. If <b>validate_only</b> is set, parse, warn and
615  * return as normal, but don't actually change the configured services. */
616 int
617 hs_config_service_all(const or_options_t *options, int validate_only)
618 {
619  int ret = -1;
620  config_line_t *remaining = NULL;
621  smartlist_t *new_service_list = NULL;
622 
623  tor_assert(options);
624 
625  /* Newly configured service are put in that list which is then used for
626  * validation and staging for >= v3. */
627  new_service_list = smartlist_new();
628 
629  /* We need to start with a HiddenServiceDir line */
630  if (options->RendConfigLines &&
631  strcasecmp(options->RendConfigLines->key, SECTION_HEADER)) {
632  log_warn(LD_CONFIG, "%s with no preceding %s directive",
633  options->RendConfigLines->key, SECTION_HEADER);
634  goto err;
635  }
636 
637  remaining = config_lines_dup(options->RendConfigLines);
638  while (remaining) {
639  config_line_t *section = remaining;
640  remaining = config_lines_partition(section, SECTION_HEADER);
641 
642  /* Try to configure this service now. On success, it will be added to the
643  * list and validated against the service in that same list. */
644  int rv = config_service(section, options, new_service_list);
645  config_free_lines(section);
646  if (rv < 0) {
647  config_free_lines(remaining);
648  goto err;
649  }
650  }
651 
652  /* In non validation mode, we'll stage those services we just successfully
653  * configured. Service ownership is transferred from the list to the global
654  * state. If any service is invalid, it will be removed from the list and
655  * freed. All versions are handled in that function. */
656  if (!validate_only) {
657  stage_services(new_service_list);
658  } else {
659  /* We've just validated that we were able to build a clean working list of
660  * services. We don't need those objects anymore. */
661  SMARTLIST_FOREACH(new_service_list, hs_service_t *, s,
662  hs_service_free(s));
663  }
664 
665  /* Success. Note that the service list has no ownership of its content. */
666  ret = 0;
667  goto end;
668 
669  err:
670  SMARTLIST_FOREACH(new_service_list, hs_service_t *, s, hs_service_free(s));
671 
672  end:
673  smartlist_free(new_service_list);
674  /* Tor main should call the free all function on error. */
675  return ret;
676 }
677 
678 /** From a set of <b>options</b>, setup every client authorization found.
679  * Return 0 on success or -1 on failure. If <b>validate_only</b> is set,
680  * parse, warn and return as normal, but don't actually change the
681  * configured state. */
682 int
683 hs_config_client_auth_all(const or_options_t *options, int validate_only)
684 {
685  int ret = -1;
686 
687  /* Configure v3 authorization. */
688  if (hs_config_client_authorization(options, validate_only) < 0) {
689  goto done;
690  }
691 
692  /* Success. */
693  ret = 0;
694  done:
695  return ret;
696 }
697 
698 /**
699  * Free all resources held by the hs_config.c module.
700  **/
701 void
703 {
704  config_mgr_free(hs_opts_mgr);
705 }
Macros for generating a configuration struct from a list of its individual fields.
const char * name
Definition: config.c:2443
config_line_t * config_lines_partition(config_line_t *inp, const char *header)
Definition: confline.c:266
config_line_t * config_lines_dup(const config_line_t *inp)
Definition: confline.c:226
Header for confline.c.
void config_init(const config_mgr_t *mgr, void *options)
Definition: confmgt.c:1158
void config_mgr_freeze(config_mgr_t *mgr)
Definition: confmgt.c:285
void * config_new(const config_mgr_t *mgr)
Definition: confmgt.c:387
config_mgr_t * config_mgr_new(const config_format_t *toplevel_fmt)
Definition: confmgt.c:145
validation_status_t config_validate(const config_mgr_t *mgr, const void *old_options, void *options, char **msg_out)
Definition: confmgt.c:1272
int config_assign(const config_mgr_t *mgr, void *options, config_line_t *list, unsigned config_assign_flags, char **msg)
Definition: confmgt.c:937
Header for confmgt.c.
validation_status_t
Definition: confmgt.h:83
const char * escaped(const char *s)
Definition: escape.c:126
int hs_config_client_authorization(const or_options_t *options, int validate_only)
Definition: hs_client.c:2351
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)
Definition: hs_common.c:200
hs_port_config_t * hs_parse_port_config(const char *string, const char *sep, char **err_msg_out)
Definition: hs_common.c:685
Header file containing common data for the whole HS subsystem.
#define NUM_INTRO_POINTS_DEFAULT
Definition: hs_common.h:30
#define HS_VERSION_MAX
Definition: hs_common.h:27
#define HS_VERSION_MIN
Definition: hs_common.h:25
#define HS_VERSION_THREE
Definition: hs_common.h:23
int hs_config_client_auth_all(const or_options_t *options, int validate_only)
Definition: hs_config.c:683
static int config_service_v3(const hs_opts_t *hs_opts, hs_service_config_t *config)
Definition: hs_config.c:336
static int config_generic_service(const hs_opts_t *hs_opts, const or_options_t *options, hs_service_t *service)
Definition: hs_config.c:421
void hs_config_free_all(void)
Definition: hs_config.c:702
#define CHECK_OOB(opts, name, low, high)
Definition: hs_config.c:177
int hs_config_service_all(const or_options_t *options, int validate_only)
Definition: hs_config.c:617
static int config_learn_service_version(hs_service_t *service)
Definition: hs_config.c:212
static bool check_value_oob(int i, const char *name, int low, int high)
Definition: hs_config.c:159
static hs_circuit_id_protocol_t helper_parse_circuit_id_protocol(const char *key, const char *value, int *ok)
Definition: hs_config.c:185
static void stage_services(smartlist_t *service_list)
Definition: hs_config.c:99
#define hs_opts_free(opts)
Definition: hs_config.c:86
static const char SECTION_HEADER[]
Definition: hs_config.c:230
static const config_mgr_t * get_hs_opts_mgr(void)
Definition: hs_config.c:61
static config_mgr_t * hs_opts_mgr
Definition: hs_config.c:55
static int config_service(config_line_t *line, const or_options_t *options, smartlist_t *service_list)
Definition: hs_config.c:512
static hs_opts_t * hs_opts_new(void)
Definition: hs_config.c:74
#define HS_OPTS_MAGIC
Definition: hs_config.c:44
static int config_has_invalid_options(const config_line_t *line_, const hs_service_t *service)
Definition: hs_config.c:240
static int service_is_duplicate_in_list(const smartlist_t *service_list, const hs_service_t *service)
Definition: hs_config.c:113
static int config_validate_service(const hs_service_config_t *config)
Definition: hs_config.c:304
Header file containing configuration ABI/API for the HS subsystem.
int hs_ob_parse_config_file(hs_service_config_t *config)
Definition: hs_ob.c:221
Header file for the specific code for onion balance.
void hs_service_stage_services(const smartlist_t *service_list)
Definition: hs_service.c:4294
hs_service_t * hs_service_new(const or_options_t *options)
Definition: hs_service.c:4339
int hs_service_get_version_from_key(const hs_service_t *service)
Definition: hs_service.c:4196
Header file containing service data for the HS subsystem.
hs_circuit_id_protocol_t
Definition: hs_service.h:194
@ HS_CIRCUIT_ID_PROTOCOL_NONE
Definition: hs_service.h:196
@ HS_CIRCUIT_ID_PROTOCOL_HAPROXY
Definition: hs_service.h:199
#define hs_service_free(s)
Definition: hs_service.h:343
#define LD_REND
Definition: log.h:84
#define LD_CONFIG
Definition: log.h:68
#define tor_free(p)
Definition: malloc.h:56
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
Definition: hs_service.h:253
uint64_t max_streams_per_rdv_circuit
Definition: hs_service.h:223
unsigned int is_single_onion
Definition: hs_service.h:243
smartlist_t * ports
Definition: hs_service.h:214
unsigned int dir_group_readable
Definition: hs_service.h:247
unsigned int hs_version_explicitly_set
Definition: hs_service.h:211
unsigned int max_streams_close_circuit
Definition: hs_service.h:227
unsigned int is_ephemeral
Definition: hs_service.h:250
unsigned int has_dos_defense_enabled
Definition: hs_service.h:256
unsigned int num_intro_points
Definition: hs_service.h:231
unsigned int allow_unknown_ports
Definition: hs_service.h:239
hs_service_config_t config
Definition: hs_service.h:313
struct config_line_t * RendConfigLines
#define tor_assert_nonfatal_unreached()
Definition: util_bug.h:176
#define tor_assert(expr)
Definition: util_bug.h:102