|
@@ -218,6 +218,7 @@ rend_service_free_all(void)
|
|
|
|
|
|
/** Validate <b>service</b> and add it to rend_service_list if possible.
|
|
|
* Return 0 on success. On failure, free <b>service</b> and return -1.
|
|
|
+ * Takes ownership of <b>service</b>.
|
|
|
*/
|
|
|
static int
|
|
|
rend_add_service(rend_service_t *service)
|
|
@@ -444,6 +445,34 @@ rend_service_port_config_free(rend_service_port_config_t *p)
|
|
|
tor_free(p);
|
|
|
}
|
|
|
|
|
|
+/* Check the directory for <b>service</b>, and add the service to the global
|
|
|
+ * list if <b>validate_only</b> is false.
|
|
|
+ * If <b>validate_only</b> is true, free the service.
|
|
|
+ * If <b>service</b> is NULL, ignore it, and return 0.
|
|
|
+ * Returns 0 on success, and -1 on failure.
|
|
|
+ * Takes ownership of <b>service</b>.
|
|
|
+ */
|
|
|
+static int
|
|
|
+rend_service_check_dir_and_add(const or_options_t *options,
|
|
|
+ rend_service_t *service,
|
|
|
+ int validate_only)
|
|
|
+{
|
|
|
+ if (service) { /* register the one we just finished parsing */
|
|
|
+ if (rend_service_check_private_dir(options, service, !validate_only)
|
|
|
+ < 0) {
|
|
|
+ rend_service_free(service);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (validate_only)
|
|
|
+ rend_service_free(service);
|
|
|
+ else
|
|
|
+ rend_add_service(service);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/** Set up rend_service_list, based on the values of HiddenServiceDir and
|
|
|
* HiddenServicePort in <b>options</b>. Return 0 on success and -1 on
|
|
|
* failure. (If <b>validate_only</b> is set, parse, warn and return as
|
|
@@ -465,17 +494,12 @@ rend_config_services(const or_options_t *options, int validate_only)
|
|
|
|
|
|
for (line = options->RendConfigLines; line; line = line->next) {
|
|
|
if (!strcasecmp(line->key, "HiddenServiceDir")) {
|
|
|
- if (service) { /* register the one we just finished parsing */
|
|
|
- if (rend_service_check_private_dir(options, service, !validate_only)
|
|
|
- < 0) {
|
|
|
- rend_service_free(service);
|
|
|
+ /* register the service we just finished parsing
|
|
|
+ * this code registers every service except the last one parsed,
|
|
|
+ * which is registered below the loop */
|
|
|
+ if (rend_service_check_dir_and_add(options, service, !validate_only)
|
|
|
+ < 0) {
|
|
|
return -1;
|
|
|
- }
|
|
|
-
|
|
|
- if (validate_only)
|
|
|
- rend_service_free(service);
|
|
|
- else
|
|
|
- rend_add_service(service);
|
|
|
}
|
|
|
service = tor_malloc_zero(sizeof(rend_service_t));
|
|
|
service->directory = tor_strdup(line->value);
|
|
@@ -681,17 +705,12 @@ rend_config_services(const or_options_t *options, int validate_only)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if (service) {
|
|
|
- if (rend_service_check_private_dir(options, service, !validate_only) < 0) {
|
|
|
- rend_service_free(service);
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- if (validate_only) {
|
|
|
- rend_service_free(service);
|
|
|
- } else {
|
|
|
- rend_add_service(service);
|
|
|
- }
|
|
|
+ /* register the final service after we have finished parsing all services
|
|
|
+ * this code only registers the last service, other services are registered
|
|
|
+ * within the loop */
|
|
|
+ if (rend_service_check_dir_and_add(options, service, !validate_only)
|
|
|
+ < 0) {
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
/* If this is a reload and there were hidden services configured before,
|