|
@@ -275,8 +275,11 @@ rend_add_service(smartlist_t *service_list, rend_service_t *service)
|
|
|
int i;
|
|
|
rend_service_port_config_t *p;
|
|
|
|
|
|
-
|
|
|
+ tor_assert(service);
|
|
|
+
|
|
|
smartlist_t *s_list = rend_get_service_list_mutable(service_list);
|
|
|
+
|
|
|
+ * check for duplicate services */
|
|
|
if (BUG(!s_list)) {
|
|
|
return -1;
|
|
|
}
|
|
@@ -333,6 +336,7 @@ rend_add_service(smartlist_t *service_list, rend_service_t *service)
|
|
|
* lock file. But this is enough to detect a simple mistake that
|
|
|
* at least one person has actually made.
|
|
|
*/
|
|
|
+ tor_assert(s_list);
|
|
|
if (!rend_service_is_ephemeral(service)) {
|
|
|
|
|
|
SMARTLIST_FOREACH(s_list, rend_service_t*, ptr,
|
|
@@ -371,6 +375,8 @@ rend_add_service(smartlist_t *service_list, rend_service_t *service)
|
|
|
#endif
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ tor_assert(s_list);
|
|
|
smartlist_add(s_list, service);
|
|
|
return 0;
|
|
|
}
|
|
@@ -527,20 +533,13 @@ rend_service_check_dir_and_add(smartlist_t *service_list,
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- if (validate_only) {
|
|
|
- rend_service_free(service);
|
|
|
- return 0;
|
|
|
- } else {
|
|
|
-
|
|
|
- smartlist_t *s_list = rend_get_service_list_mutable(service_list);
|
|
|
-
|
|
|
- * are NULL, and validate_only is false, we exit earlier in the function
|
|
|
- */
|
|
|
- if (BUG(!s_list)) {
|
|
|
- return -1;
|
|
|
- }
|
|
|
- return rend_add_service(s_list, service);
|
|
|
+ smartlist_t *s_list = rend_get_service_list_mutable(service_list);
|
|
|
+
|
|
|
+ * check for duplicate services */
|
|
|
+ if (BUG(!s_list)) {
|
|
|
+ return -1;
|
|
|
}
|
|
|
+ return rend_add_service(s_list, service);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -555,19 +554,19 @@ rend_config_services(const or_options_t *options, int validate_only)
|
|
|
rend_service_t *service = NULL;
|
|
|
rend_service_port_config_t *portcfg;
|
|
|
smartlist_t *old_service_list = NULL;
|
|
|
+ smartlist_t *temp_service_list = NULL;
|
|
|
int ok = 0;
|
|
|
|
|
|
- if (!validate_only) {
|
|
|
- old_service_list = rend_service_list;
|
|
|
- rend_service_list = smartlist_new();
|
|
|
- }
|
|
|
+
|
|
|
+ * consistency with each other */
|
|
|
+ temp_service_list = smartlist_new();
|
|
|
|
|
|
for (line = options->RendConfigLines; line; line = line->next) {
|
|
|
if (!strcasecmp(line->key, "HiddenServiceDir")) {
|
|
|
|
|
|
* this code registers every service except the last one parsed,
|
|
|
* which is registered below the loop */
|
|
|
- if (rend_service_check_dir_and_add(NULL, options, service,
|
|
|
+ if (rend_service_check_dir_and_add(temp_service_list, options, service,
|
|
|
validate_only) < 0) {
|
|
|
return -1;
|
|
|
}
|
|
@@ -783,11 +782,27 @@ rend_config_services(const or_options_t *options, int validate_only)
|
|
|
|
|
|
* this code only registers the last service, other services are registered
|
|
|
* within the loop. It is ok for this service to be NULL, it is ignored. */
|
|
|
- if (rend_service_check_dir_and_add(NULL, options, service,
|
|
|
+ if (rend_service_check_dir_and_add(temp_service_list, options, service,
|
|
|
validate_only) < 0) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ if (validate_only) {
|
|
|
+ SMARTLIST_FOREACH(temp_service_list, rend_service_t *, ptr,
|
|
|
+ rend_service_free(ptr));
|
|
|
+ smartlist_free(temp_service_list);
|
|
|
+ temp_service_list = NULL;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ * Since we have now replaced the global service list, from this point on we
|
|
|
+ * must succeed, or die trying. */
|
|
|
+ old_service_list = rend_service_list;
|
|
|
+ rend_service_list = temp_service_list;
|
|
|
+ temp_service_list = NULL;
|
|
|
+
|
|
|
|
|
|
* keep the introduction points that are still needed and close the
|
|
|
* other ones. */
|