From 49604ce507839f08822db7371888ec826cf14d84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20L=C3=BCssing?= Date: Tue, 22 Mar 2022 02:06:38 +0100 Subject: [PATCH] respondd: add provider "respondd-providers" to list registrations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an internal respondd provider "respondd-providers" which allows a respondd querier to query which providers are registered on a node. Example output: { "respondd-providers": [ "neighbours", "nodeinfo", "statistics", "statistics-extended" ] } This can be useful for providers which are known to be bulky, where the actual data is better queried via HTTP/TCP instead. But where such a provider is only present on a few nodes, so you'd want to avoid trying each node via HTTP. Signed-off-by: Linus Lüssing --- net/respondd/src/respondd.c | 54 ++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/net/respondd/src/respondd.c b/net/respondd/src/respondd.c index 70ea347..0d5592f 100644 --- a/net/respondd/src/respondd.c +++ b/net/respondd/src/respondd.c @@ -78,6 +78,11 @@ struct provider_list { respondd_provider provider; }; +struct key_list { + struct key_list *next; + char *key; +}; + struct request_type { struct provider_list *providers; @@ -101,6 +106,7 @@ struct request_schedule { static int64_t now; static struct hsearch_data htab; +static struct key_list *keys; static struct json_object * merge_json(struct json_object *a, struct json_object *b); @@ -272,6 +278,23 @@ static void load_cache_time(struct request_type *r, const char *name) { } +static void add_key(const char *key) { + struct key_list **pos, *pentry; + int i = 0; + + for (pos = &keys; *pos; pos = &(*pos)->next) { + if (strcmp(key, (*pos)->key) == 0) + return; + if (strcmp(key, (*pos)->key) < 0) + break; + } + + pentry = malloc(sizeof(*pentry)); + pentry->key = strdup(key); + pentry->next = *pos; + *pos = pentry; +} + static void add_provider(const char *name, const struct respondd_provider_info *provider) { ENTRY key = { .key = (char *)provider->request, @@ -306,6 +329,31 @@ static void add_provider(const char *name, const struct respondd_provider_info * *pos = pentry; } +static struct json_object *respondd_provider_providers(void) { + struct key_list **pos; + struct json_object *provider; + struct json_object *ret = json_object_new_array(); + + if (!ret) + return NULL; + + for (pos = &keys; *pos; pos = &(*pos)->next) { + provider = json_object_new_string((*pos)->key); + json_object_array_add(ret, provider); + } + + return ret; +} + +static void add_providers_provider(void) { + const struct respondd_provider_info providers[] = { + {"respondd-providers", respondd_provider_providers}, + {} + }; + + add_provider("respondd", providers); +} + static void load_providers(const char *path) { update_time(); @@ -339,10 +387,14 @@ static void load_providers(const char *path) { if (!providers) continue; - for (; providers->request; providers++) + for (; providers->request; providers++) { add_provider(ent->d_name, providers); + add_key(providers->request); + } } + add_providers_provider(); + closedir(dir); out: