aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2019-06-18 19:16:57 -0400
committerNick Mathewson <nickm@torproject.org>2019-06-24 17:52:00 -0400
commite16b90b88a76fb82702ae26c54834aca6c591d64 (patch)
tree6bd463bf53b0b30ebb7be6b46b24ee8dfdc9642f /src
parent705bda859ed8bbdd753d587b9814de4af3afee80 (diff)
downloadtor-e16b90b88a76fb82702ae26c54834aca6c591d64.tar.gz
tor-e16b90b88a76fb82702ae26c54834aca6c591d64.zip
Partially port routerset to being a full-fledged config type again.
Diffstat (limited to 'src')
-rw-r--r--src/app/config/confparse.c27
-rw-r--r--src/feature/nodelist/routerset.c62
-rw-r--r--src/feature/nodelist/routerset.h3
3 files changed, 70 insertions, 22 deletions
diff --git a/src/app/config/confparse.c b/src/app/config/confparse.c
index bc2ab24e4f..a02aa26e82 100644
--- a/src/app/config/confparse.c
+++ b/src/app/config/confparse.c
@@ -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;
}
diff --git a/src/feature/nodelist/routerset.c b/src/feature/nodelist/routerset.c
index e801fd81b1..ad42e8e101 100644
--- a/src/feature/nodelist/routerset.c
+++ b/src/feature/nodelist/routerset.c
@@ -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
+};
diff --git a/src/feature/nodelist/routerset.h b/src/feature/nodelist/routerset.h
index ca8b6fed93..9d184c9852 100644
--- a/src/feature/nodelist/routerset.h
+++ b/src/feature/nodelist/routerset.h
@@ -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"