]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Partially port routerset to being a full-fledged config type again.
authorNick Mathewson <nickm@torproject.org>
Tue, 18 Jun 2019 23:16:57 +0000 (19:16 -0400)
committerNick Mathewson <nickm@torproject.org>
Mon, 24 Jun 2019 21:52:00 +0000 (17:52 -0400)
src/app/config/confparse.c
src/feature/nodelist/routerset.c
src/feature/nodelist/routerset.h

index bc2ab24e4f0574291c6a768b2be412dc53ada09a..a02aa26e82dbb4c4cc5814265eaa13df597a1a0b 100644 (file)
@@ -175,18 +175,8 @@ config_assign_value(const config_format_t *fmt, void *options,
 
   if (var->type == CONFIG_TYPE_ROUTERSET) {
     // XXXX make the backend extensible so that we don't have to
-    // XXXX handle ROUTERSET specially.
-
-    if (*(routerset_t**)lvalue) {
-      routerset_free(*(routerset_t**)lvalue);
-    }
-    *(routerset_t**)lvalue = routerset_new();
-    if (routerset_parse(*(routerset_t**)lvalue, c->value, c->key)<0) {
-      tor_asprintf(msg, "Invalid exit list '%s' for option '%s'",
-                   c->value, c->key);
-      return -1;
-    }
-    return 0;
+    // XXXX special-case this type.
+    return typed_var_kvassign_ex(lvalue, c, msg, &routerset_type_defn);
   }
 
   return typed_var_kvassign(lvalue, c, msg, var->type);
@@ -377,10 +367,8 @@ config_get_assigned_option(const config_format_t *fmt, const void *options,
 
   if (var->type == CONFIG_TYPE_ROUTERSET) {
     // XXXX make the backend extensible so that we don't have to
-    // XXXX handle ROUTERSET specially.
-    result = tor_malloc_zero(sizeof(config_line_t));
-    result->key = tor_strdup(var->name);
-    result->value = routerset_to_string(*(routerset_t**)value);
+    // XXXX special-case this type.
+    result = typed_var_kvencode_ex(var->name, value, &routerset_type_defn);
   } else {
     result = typed_var_kvencode(var->name, value, var->type);
   }
@@ -512,12 +500,7 @@ config_clear(const config_format_t *fmt, void *options,
   void *lvalue = STRUCT_VAR_P(options, var->var_offset);
   (void)fmt; /* unused */
   if (var->type == CONFIG_TYPE_ROUTERSET) {
-    // XXXX make the backend extensible so that we don't have to
-    // XXXX handle ROUTERSET specially.
-    if (*(routerset_t**)lvalue) {
-      routerset_free(*(routerset_t**)lvalue);
-      *(routerset_t**)lvalue = NULL;
-    }
+    typed_var_free_ex(lvalue, &routerset_type_defn);
     return;
   }
 
index e801fd81b1f3e20c18f48ef2550c88e9c22fd4bd..ad42e8e10156691aac0392588f9579c64ca373a7 100644 (file)
@@ -34,6 +34,9 @@ n * Copyright (c) 2001-2004, Roger Dingledine.
 #include "feature/nodelist/nickname.h"
 #include "feature/nodelist/nodelist.h"
 #include "feature/nodelist/routerset.h"
+#include "lib/conf/conftypes.h"
+#include "lib/confmgt/typedvar.h"
+#include "lib/encoding/confline.h"
 #include "lib/geoip/geoip.h"
 
 #include "core/or/addr_policy_st.h"
@@ -41,6 +44,7 @@ n * Copyright (c) 2001-2004, Roger Dingledine.
 #include "feature/nodelist/node_st.h"
 #include "feature/nodelist/routerinfo_st.h"
 #include "feature/nodelist/routerstatus_st.h"
+#include "lib/confmgt/var_type_def_st.h"
 
 /** Return a new empty routerset. */
 routerset_t *
@@ -461,3 +465,61 @@ routerset_free_(routerset_t *routerset)
   bitarray_free(routerset->countries);
   tor_free(routerset);
 }
+
+static int
+routerset_kv_parse(void *target, const config_line_t *line, char **errmsg,
+                  const void *params)
+{
+  (void)params;
+  routerset_t **p = (routerset_t**)target;
+  routerset_free(*p); // clear the old value, if any.
+  routerset_t *rs = routerset_new();
+  if (routerset_parse(rs, line->value, line->key) < 0) {
+    routerset_free(rs);
+    *errmsg = tor_strdup("Invalid router list.");
+    return -1;
+  } else {
+    *p = rs;
+    return 0;
+  }
+}
+
+static char *
+routerset_encode(const void *value, const void *params)
+{
+  (void)params;
+  const routerset_t **p = (const routerset_t**)value;
+  return routerset_to_string(*p);
+}
+
+static void
+routerset_clear(void *value, const void *params)
+{
+  (void)params;
+  routerset_t **p = (routerset_t**)value;
+  routerset_free(*p); // sets *p to NULL.
+}
+
+static int
+routerset_copy(void *dest, const void *src, const void *params)
+{
+  (void)params;
+  routerset_t **output = (routerset_t**)dest;
+  const routerset_t *input = *(routerset_t**)src;
+  routerset_free(*output); // sets *output to NULL
+  *output = routerset_new();
+  routerset_union(*output, input);
+  return 0;
+}
+
+static const var_type_fns_t routerset_type_fns = {
+  .kv_parse = routerset_kv_parse,
+  .encode = routerset_encode,
+  .clear = routerset_clear,
+  .copy = routerset_copy
+};
+
+const var_type_def_t routerset_type_defn = {
+  .name = "RouterList",
+  .fns = &routerset_type_fns
+};
index ca8b6fed9327d0090087d668fb677d63ab16ca36..9d184c98523bd15e05eded0a4de8d67af3b55c46 100644 (file)
@@ -44,6 +44,9 @@ void routerset_free_(routerset_t *routerset);
 #define routerset_free(rs) FREE_AND_NULL(routerset_t, routerset_free_, (rs))
 int routerset_len(const routerset_t *set);
 
+struct var_type_def_t;
+extern const struct var_type_def_t routerset_type_defn;
+
 #ifdef ROUTERSET_PRIVATE
 #include "lib/container/bitarray.h"