]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
Moved cookies before iterate layer.
authorKarel Slany <karel.slany@nic.cz>
Tue, 31 May 2016 12:51:41 +0000 (14:51 +0200)
committerOndřej Surý <ondrej@sury.org>
Thu, 11 Aug 2016 12:06:45 +0000 (14:06 +0200)
daemon/engine.c
lib/layer/cookies.c [moved from modules/cookies/cookies.c with 66% similarity]
lib/lib.mk
lib/module.c
modules/cookies/cookies.mk [deleted file]
modules/cookies_control/cookies_control.c [new file with mode: 0644]
modules/cookies_control/cookies_control.mk [new file with mode: 0644]
modules/modules.mk

index ad852ba601a9313e760fb4d554bc1ececd1faead..4c346aab4928bf307eb3b1390851f63433825e32 100644 (file)
@@ -471,6 +471,7 @@ static int init_resolver(struct engine *engine)
        }
 
        /* Load basic modules */
+       engine_register(engine, "cookies", NULL, NULL);
        engine_register(engine, "iterate", NULL, NULL);
        engine_register(engine, "validate", NULL, NULL);
        engine_register(engine, "rrcache", NULL, NULL);
similarity index 66%
rename from modules/cookies/cookies.c
rename to lib/layer/cookies.c
index 3c972db42859dd1671f4f74c2218d74491d0f91a..829ac0dffdb2f45e3e1200df16be50ae98eddcbc 100644 (file)
@@ -25,7 +25,6 @@
 #include <libknot/rrtype/opt_cookie.h> // branch dns-cookies-wip
 #include <stdlib.h>
 #include <string.h>
-#include <time.h>
 
 #include "daemon/engine.h"
 #include "lib/cookies/cache.h"
@@ -352,10 +351,9 @@ static int check_response(knot_layer_t *ctx, knot_pkt_t *pkt)
 
        uint16_t rcode = knot_pkt_get_ext_rcode(pkt);
        if (rcode == KNOT_RCODE_BADCOOKIE) {
-               /* TODO -- Fall back to TCP after a limited number of retries. */
-               DEBUG_MSG(NULL, "%s'n", "falling back to TCP");
+               DEBUG_MSG(NULL, "%s\n", "falling back to TCP");
                qry->flags |= QUERY_TCP;
-               return KNOT_STATE_PRODUCE;
+               return KNOT_STATE_CONSUME;
        }
 
        print_packet_dflt(pkt);
@@ -363,197 +361,7 @@ static int check_response(knot_layer_t *ctx, knot_pkt_t *pkt)
        return ctx->state;
 }
 
-/** Find storage API with given prefix. */
-static struct storage_api *find_storage_api(const storage_registry_t *registry,
-                                            const char *prefix)
-{
-       assert(registry);
-       assert(prefix);
-
-       for (unsigned i = 0; i < registry->len; ++i) {
-               struct storage_api *storage = &registry->at[i];
-               if (strcmp(storage->prefix, "lmdb://") == 0) {
-                       return storage;
-               }
-       }
-
-       return NULL;
-}
-
-#define NAME_ENABLED "enabled"
-#define NAME_CLIENT_SECRET "client_secret"
-
-static bool aply_enabled(struct cookies_control *cntrl, const JsonNode *node)
-{
-       if (node->tag == JSON_BOOL) {
-               cntrl->enabled = node->bool_;
-               return true;
-       }
-
-       return false;
-}
-
-static struct secret_quantity *new_sq_str(const JsonNode *node)
-{
-       assert(node && node->tag == JSON_STRING);
-
-       size_t len = strlen(node->string_);
-
-       struct secret_quantity *sq = malloc(sizeof(*sq) + len);
-       if (!sq) {
-               return NULL;
-       }
-       sq->size = len;
-       memcpy(sq->data, node->string_, len);
-
-       return sq;
-}
-
-#define holds_char(x) ((x) >= 0 && (x) <= 255)
-
-static struct secret_quantity *new_sq_array(const JsonNode *node)
-{
-       assert(node && node->tag == JSON_ARRAY);
-
-       const JsonNode *element = NULL;
-       size_t cnt = 0;
-       json_foreach(element, node) {
-               if (element->tag != JSON_NUMBER || !holds_char(element->number_)) {
-                       return NULL;
-               }
-               ++cnt;
-       }
-       if (cnt == 0) {
-               return NULL;
-       }
-
-       struct secret_quantity *sq = malloc(sizeof(*sq) + cnt);
-       if (!sq) {
-               return NULL;
-       }
-
-       sq->size = cnt;
-       cnt = 0;
-       json_foreach(element, node) {
-               sq->data[cnt++] = (uint8_t) element->number_;
-       }
-
-       return sq;
-}
-
-static bool apply_client_secret(struct cookies_control *cntrl, const JsonNode *node)
-{
-       struct secret_quantity *sq = NULL;
-
-       switch (node->tag) {
-       case JSON_STRING:
-               sq = new_sq_str(node);
-               break;
-       case JSON_ARRAY:
-               sq = new_sq_array(node);
-               break;
-       default:
-               break;
-       }
-
-       if (!sq) {
-               return false;
-       }
-
-       if (sq->size == cntrl->current_cs->size &&
-           memcmp(sq->data, cntrl->current_cs->data, sq->size) == 0) {
-               /* Ignore same values. */
-               free(sq);
-               return true;
-       }
-
-       struct secret_quantity *tmp = cntrl->recent_cs;
-       cntrl->recent_cs = cntrl->current_cs;
-       cntrl->current_cs = sq;
-
-       if (tmp && tmp != &dflt_cs) {
-               free(tmp);
-       }
-
-       return true;
-}
-
-static bool apply_configuration(struct cookies_control *cntrl, const JsonNode *node)
-{
-       assert(cntrl && node);
-
-       if (!node->key) {
-               /* All top most nodes must have names. */
-               return false;
-       }
-
-       if (strcmp(node->key, NAME_ENABLED) == 0) {
-               return aply_enabled(cntrl, node);
-       } else if (strcmp(node->key, NAME_CLIENT_SECRET) == 0) {
-               return apply_client_secret(cntrl, node);
-       }
-
-       return false;
-}
-
-static bool read_secret(JsonNode *root, struct cookies_control *cntrl)
-{
-       assert(root && cntrl);
-
-       JsonNode *array = json_mkarray();
-       if (!array) {
-               return false;
-       }
-
-       for (size_t i = 0; i < cntrl->current_cs->size; ++i) {
-               JsonNode *element = json_mknumber(cntrl->current_cs->data[i]);
-               if (!element) {
-                       goto fail;
-               }
-               json_append_element(array, element);
-       }
-
-       json_append_member(root, NAME_CLIENT_SECRET, array);
-
-       return true;
-
-fail:
-       if (array) {
-               json_delete(array);
-       }
-       return false;
-}
-
-/**
- * Get/set DNS cookie related stuff.
- *
- * Input: { name: value, ... }
- * Output: current configuration
- */
-static char *cookies_config(void *env, struct kr_module *module, const char *args)
-{
-       if (args && strlen(args) > 0) {
-               JsonNode *node;
-               JsonNode *root_node = json_decode(args);
-               json_foreach (node, root_node) {
-                       apply_configuration(&kr_cookies_control, node);
-               }
-               json_delete(root_node);
-       }
-
-       /* Return current configuration. */
-       char *result = NULL;
-       JsonNode *root_node = json_mkobject();
-       json_append_member(root_node, NAME_ENABLED, json_mkbool(kr_cookies_control.enabled));
-       read_secret(root_node, &kr_cookies_control);
-       result = json_encode(root_node);
-       json_delete(root_node);
-       return result;
-}
-
-/*
- * Module implementation.
- */
+/** Module implementation. */
 
 KR_EXPORT
 const knot_layer_api_t *cookies_layer(struct kr_module *module)
@@ -566,73 +374,4 @@ const knot_layer_api_t *cookies_layer(struct kr_module *module)
        return &_layer;
 }
 
-KR_EXPORT
-int cookies_init(struct kr_module *module)
-{
-       const char *storage_prefix = "lmdb://";
-       struct engine *engine = module->data;
-       DEBUG_MSG(NULL, "initialising with engine %p\n", (void *) engine);
-
-       memset(&kr_cookies_control, 0, sizeof(kr_cookies_control));
-
-       kr_cookies_control.enabled = false;
-
-       kr_cookies_control.current_cs = &dflt_cs;
-
-       memset(&kr_cookies_control.cache, 0, sizeof(kr_cookies_control.cache));
-
-       struct storage_api *lmdb_storage_api = find_storage_api(&engine->storage_registry,
-                                                               storage_prefix);
-       DEBUG_MSG(NULL, "found storage API %p for prefix '%s'\n",
-                 (void *) lmdb_storage_api, storage_prefix);
-
-       struct knot_db_lmdb_opts opts = KNOT_DB_LMDB_OPTS_INITIALIZER;
-       opts.path = "cookies_db";
-       //opts.dbname = "cookies";
-       opts.mapsize = 1024 * 1024 * 1024;
-       opts.maxdbs = 2;
-       opts.flags.env = 0x80000 | 0x100000; /* MDB_WRITEMAP|MDB_MAPASYNC */
-
-       errno = 0;
-       int ret = kr_cache_open(&kr_cookies_control.cache,
-                               lmdb_storage_api->api(), &opts, engine->pool);
-       DEBUG_MSG(NULL, "cache_open retval %d: %s\n", ret, kr_strerror(ret));
-
-       module->data = NULL;
-
-       return kr_ok();
-}
-
-KR_EXPORT
-int cookies_deinit(struct kr_module *module)
-{
-       kr_cookies_control.enabled = false;
-
-       if (kr_cookies_control.recent_cs &&
-           kr_cookies_control.recent_cs != &dflt_cs) {
-               free(kr_cookies_control.recent_cs);
-       }
-       kr_cookies_control.recent_cs = NULL;
-
-       if (kr_cookies_control.current_cs &&
-           kr_cookies_control.current_cs != &dflt_cs) {
-               free(kr_cookies_control.current_cs);
-       }
-       kr_cookies_control.current_cs = &dflt_cs;
-
-       kr_cache_close(&kr_cookies_control.cache);
-
-       return kr_ok();
-}
-
-KR_EXPORT
-struct kr_prop *cookies_props(void)
-{
-       static struct kr_prop prop_list[] = {
-           { &cookies_config, "config", "Empty value to return current configuration.", },
-           { NULL, NULL, NULL }
-       };
-       return prop_list;
-}
-
-KR_MODULE_EXPORT(cookies);
+KR_MODULE_EXPORT(cookies)
index 4dafe5c8e37d4bafb14f30fbf389d1f020d87eee..60dd40fe0fd647b433d0986193a4040fff2b55f3 100644 (file)
@@ -1,6 +1,7 @@
 libkres_SOURCES := \
        contrib/fnv/hash_64a.c \
        lib/generic/map.c      \
+       lib/layer/cookies.c    \
        lib/layer/iterate.c    \
        lib/layer/validate.c   \
        lib/layer/rrcache.c    \
index 7c7a1398df7cd14bceac82ba8499a1ae1d1ae6b8..99c96d5fe4c66bdc02f739cdafee9f0a3488187d 100644 (file)
 #include "lib/module.h"
 
 /* List of embedded modules */
+const knot_layer_api_t *cookies_layer(struct kr_module *module);
 const knot_layer_api_t *iterate_layer(struct kr_module *module);
 const knot_layer_api_t *validate_layer(struct kr_module *module);
 const knot_layer_api_t *rrcache_layer(struct kr_module *module);
 const knot_layer_api_t *pktcache_layer(struct kr_module *module);
 static const struct kr_module embedded_modules[] = {
+       { "cookies",  NULL, NULL, NULL, cookies_layer, NULL, NULL, NULL },
        { "iterate",  NULL, NULL, NULL, iterate_layer, NULL, NULL, NULL },
        { "validate", NULL, NULL, NULL, validate_layer, NULL, NULL, NULL },
        { "rrcache",  NULL, NULL, NULL, rrcache_layer, NULL, NULL, NULL },
diff --git a/modules/cookies/cookies.mk b/modules/cookies/cookies.mk
deleted file mode 100644 (file)
index 2960154..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-cookies_CFLAGS := -fvisibility=hidden -fPIC
-cookies_SOURCES := modules/cookies/cookies.c
-cookies_DEPEND := $(libkres)
-cookies_LIBS := $(contrib_TARGET) $(libkres_TARGET) $(libkres_LIBS)
-$(call make_c_module,cookies)
diff --git a/modules/cookies_control/cookies_control.c b/modules/cookies_control/cookies_control.c
new file mode 100644 (file)
index 0000000..643e273
--- /dev/null
@@ -0,0 +1,290 @@
+/*  Copyright (C) 2016 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <assert.h>
+#include <ccan/json/json.h>
+#include <libknot/db/db_lmdb.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "daemon/engine.h"
+#include "lib/cookies/control.h"
+#include "lib/layer.h"
+
+#define DEBUG_MSG(qry, fmt...) QRDEBUG(qry, "cookies_control",  fmt)
+
+/** Find storage API with given prefix. */
+static struct storage_api *find_storage_api(const storage_registry_t *registry,
+                                            const char *prefix)
+{
+       assert(registry);
+       assert(prefix);
+
+       for (unsigned i = 0; i < registry->len; ++i) {
+               struct storage_api *storage = &registry->at[i];
+               if (strcmp(storage->prefix, "lmdb://") == 0) {
+                       return storage;
+               }
+       }
+
+       return NULL;
+}
+
+#define NAME_ENABLED "enabled"
+#define NAME_CLIENT_SECRET "client_secret"
+
+static bool aply_enabled(struct cookies_control *cntrl, const JsonNode *node)
+{
+       if (node->tag == JSON_BOOL) {
+               cntrl->enabled = node->bool_;
+               return true;
+       }
+
+       return false;
+}
+
+static struct secret_quantity *new_sq_str(const JsonNode *node)
+{
+       assert(node && node->tag == JSON_STRING);
+
+       size_t len = strlen(node->string_);
+
+       struct secret_quantity *sq = malloc(sizeof(*sq) + len);
+       if (!sq) {
+               return NULL;
+       }
+       sq->size = len;
+       memcpy(sq->data, node->string_, len);
+
+       return sq;
+}
+
+#define holds_char(x) ((x) >= 0 && (x) <= 255)
+
+static struct secret_quantity *new_sq_array(const JsonNode *node)
+{
+       assert(node && node->tag == JSON_ARRAY);
+
+       const JsonNode *element = NULL;
+       size_t cnt = 0;
+       json_foreach(element, node) {
+               if (element->tag != JSON_NUMBER || !holds_char(element->number_)) {
+                       return NULL;
+               }
+               ++cnt;
+       }
+       if (cnt == 0) {
+               return NULL;
+       }
+
+       struct secret_quantity *sq = malloc(sizeof(*sq) + cnt);
+       if (!sq) {
+               return NULL;
+       }
+
+       sq->size = cnt;
+       cnt = 0;
+       json_foreach(element, node) {
+               sq->data[cnt++] = (uint8_t) element->number_;
+       }
+
+       return sq;
+}
+
+static bool apply_client_secret(struct cookies_control *cntrl, const JsonNode *node)
+{
+       struct secret_quantity *sq = NULL;
+
+       switch (node->tag) {
+       case JSON_STRING:
+               sq = new_sq_str(node);
+               break;
+       case JSON_ARRAY:
+               sq = new_sq_array(node);
+               break;
+       default:
+               break;
+       }
+
+       if (!sq) {
+               return false;
+       }
+
+       if (sq->size == cntrl->current_cs->size &&
+           memcmp(sq->data, cntrl->current_cs->data, sq->size) == 0) {
+               /* Ignore same values. */
+               free(sq);
+               return true;
+       }
+
+       struct secret_quantity *tmp = cntrl->recent_cs;
+       cntrl->recent_cs = cntrl->current_cs;
+       cntrl->current_cs = sq;
+
+       if (tmp && tmp != &dflt_cs) {
+               free(tmp);
+       }
+
+       return true;
+}
+
+static bool apply_configuration(struct cookies_control *cntrl, const JsonNode *node)
+{
+       assert(cntrl && node);
+
+       if (!node->key) {
+               /* All top most nodes must have names. */
+               return false;
+       }
+
+       if (strcmp(node->key, NAME_ENABLED) == 0) {
+               return aply_enabled(cntrl, node);
+       } else if (strcmp(node->key, NAME_CLIENT_SECRET) == 0) {
+               return apply_client_secret(cntrl, node);
+       }
+
+       return false;
+}
+
+static bool read_secret(JsonNode *root, struct cookies_control *cntrl)
+{
+       assert(root && cntrl);
+
+       JsonNode *array = json_mkarray();
+       if (!array) {
+               return false;
+       }
+
+       for (size_t i = 0; i < cntrl->current_cs->size; ++i) {
+               JsonNode *element = json_mknumber(cntrl->current_cs->data[i]);
+               if (!element) {
+                       goto fail;
+               }
+               json_append_element(array, element);
+       }
+
+       json_append_member(root, NAME_CLIENT_SECRET, array);
+
+       return true;
+
+fail:
+       if (array) {
+               json_delete(array);
+       }
+       return false;
+}
+
+/**
+ * Get/set DNS cookie related stuff.
+ *
+ * Input: { name: value, ... }
+ * Output: current configuration
+ */
+static char *cookies_control_config(void *env, struct kr_module *module, const char *args)
+{
+       if (args && strlen(args) > 0) {
+               JsonNode *node;
+               JsonNode *root_node = json_decode(args);
+               json_foreach (node, root_node) {
+                       apply_configuration(&kr_cookies_control, node);
+               }
+               json_delete(root_node);
+       }
+
+       /* Return current configuration. */
+       char *result = NULL;
+       JsonNode *root_node = json_mkobject();
+       json_append_member(root_node, NAME_ENABLED, json_mkbool(kr_cookies_control.enabled));
+       read_secret(root_node, &kr_cookies_control);
+       result = json_encode(root_node);
+       json_delete(root_node);
+       return result;
+}
+
+/*
+ * Module implementation.
+ */
+
+KR_EXPORT
+int cookies_control_init(struct kr_module *module)
+{
+       const char *storage_prefix = "lmdb://";
+       struct engine *engine = module->data;
+       DEBUG_MSG(NULL, "initialising with engine %p\n", (void *) engine);
+
+       memset(&kr_cookies_control, 0, sizeof(kr_cookies_control));
+
+       kr_cookies_control.enabled = false;
+
+       kr_cookies_control.current_cs = &dflt_cs;
+
+       memset(&kr_cookies_control.cache, 0, sizeof(kr_cookies_control.cache));
+
+       struct storage_api *lmdb_storage_api = find_storage_api(&engine->storage_registry,
+                                                               storage_prefix);
+       DEBUG_MSG(NULL, "found storage API %p for prefix '%s'\n",
+                 (void *) lmdb_storage_api, storage_prefix);
+
+       struct knot_db_lmdb_opts opts = KNOT_DB_LMDB_OPTS_INITIALIZER;
+       opts.path = "cookies_db";
+       //opts.dbname = "cookies";
+       opts.mapsize = 1024 * 1024 * 1024;
+       opts.maxdbs = 2;
+       opts.flags.env = 0x80000 | 0x100000; /* MDB_WRITEMAP|MDB_MAPASYNC */
+
+       errno = 0;
+       int ret = kr_cache_open(&kr_cookies_control.cache,
+                               lmdb_storage_api->api(), &opts, engine->pool);
+       DEBUG_MSG(NULL, "cache_open retval %d: %s\n", ret, kr_strerror(ret));
+
+       module->data = NULL;
+
+       return kr_ok();
+}
+
+KR_EXPORT
+int cookies_control_deinit(struct kr_module *module)
+{
+       kr_cookies_control.enabled = false;
+
+       if (kr_cookies_control.recent_cs &&
+           kr_cookies_control.recent_cs != &dflt_cs) {
+               free(kr_cookies_control.recent_cs);
+       }
+       kr_cookies_control.recent_cs = NULL;
+
+       if (kr_cookies_control.current_cs &&
+           kr_cookies_control.current_cs != &dflt_cs) {
+               free(kr_cookies_control.current_cs);
+       }
+       kr_cookies_control.current_cs = &dflt_cs;
+
+       kr_cache_close(&kr_cookies_control.cache);
+
+       return kr_ok();
+}
+
+KR_EXPORT
+struct kr_prop *cookies_control_props(void)
+{
+       static struct kr_prop prop_list[] = {
+           { &cookies_control_config, "config", "Empty value to return current configuration.", },
+           { NULL, NULL, NULL }
+       };
+       return prop_list;
+}
+
+KR_MODULE_EXPORT(cookies_control);
diff --git a/modules/cookies_control/cookies_control.mk b/modules/cookies_control/cookies_control.mk
new file mode 100644 (file)
index 0000000..8ea34e6
--- /dev/null
@@ -0,0 +1,6 @@
+cookies_control_CFLAGS := -fvisibility=hidden -fPIC
+cookies_control_SOURCES := \
+       modules/cookies_control/cookies_control.c
+cookies_control_DEPEND := $(libkres)
+cookies_control_LIBS := $(contrib_TARGET) $(libkres_TARGET) $(libkres_LIBS)
+$(call make_c_module,cookies_control)
index 331f01b1dee648c3b0e8f1e1a90ff5922f7e1e91..1bac83a1f490f2c0c24b8e46df9004cbfcc78468 100644 (file)
@@ -1,7 +1,7 @@
 # List of built-in modules
 modules_TARGETS := hints \
                    stats \
-                   cookies
+                   cookies_control
 
 # Memcached
 ifeq ($(HAS_libmemcached),yes)