aboutsummaryrefslogtreecommitdiff
path: root/external/unbound/util/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'external/unbound/util/module.c')
-rw-r--r--external/unbound/util/module.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/external/unbound/util/module.c b/external/unbound/util/module.c
index 09e276c30..f4b715d14 100644
--- a/external/unbound/util/module.c
+++ b/external/unbound/util/module.c
@@ -39,6 +39,7 @@
#include "config.h"
#include "util/module.h"
+#include "sldns/wire2str.h"
const char*
strextstate(enum module_ext_state s)
@@ -69,3 +70,169 @@ strmodulevent(enum module_ev e)
}
return "bad_event_value";
}
+
+int
+edns_known_options_init(struct module_env* env)
+{
+ env->edns_known_options_num = 0;
+ env->edns_known_options = (struct edns_known_option*)calloc(
+ MAX_KNOWN_EDNS_OPTS, sizeof(struct edns_known_option));
+ if(!env->edns_known_options) return 0;
+ return 1;
+}
+
+void
+edns_known_options_delete(struct module_env* env)
+{
+ free(env->edns_known_options);
+ env->edns_known_options = NULL;
+ env->edns_known_options_num = 0;
+}
+
+int
+edns_register_option(uint16_t opt_code, int bypass_cache_stage,
+ int no_aggregation, struct module_env* env)
+{
+ size_t i;
+ if(env->worker) {
+ log_err("invalid edns registration: "
+ "trying to register option after module init phase");
+ return 0;
+ }
+
+ /**
+ * Checking if we are full first is faster but it does not provide
+ * the option to change the flags when the array is full.
+ * It only impacts unbound initialization, leave it for now.
+ */
+ /* Check if the option is already registered. */
+ for(i=0; i<env->edns_known_options_num; i++)
+ if(env->edns_known_options[i].opt_code == opt_code)
+ break;
+ /* If it is not yet registered check if we have space to add a new one. */
+ if(i == env->edns_known_options_num) {
+ if(env->edns_known_options_num >= MAX_KNOWN_EDNS_OPTS) {
+ log_err("invalid edns registration: maximum options reached");
+ return 0;
+ }
+ env->edns_known_options_num++;
+ }
+ env->edns_known_options[i].opt_code = opt_code;
+ env->edns_known_options[i].bypass_cache_stage = bypass_cache_stage;
+ env->edns_known_options[i].no_aggregation = no_aggregation;
+ return 1;
+}
+
+int
+inplace_cb_register(void* cb, enum inplace_cb_list_type type, void* cbarg,
+ struct module_env* env, int id)
+{
+ struct inplace_cb* callback;
+ struct inplace_cb** prevp;
+ if(env->worker) {
+ log_err("invalid edns callback registration: "
+ "trying to register callback after module init phase");
+ return 0;
+ }
+
+ callback = (struct inplace_cb*)calloc(1, sizeof(*callback));
+ if(callback == NULL) {
+ log_err("out of memory during edns callback registration.");
+ return 0;
+ }
+ callback->id = id;
+ callback->next = NULL;
+ callback->cb = cb;
+ callback->cb_arg = cbarg;
+
+ prevp = (struct inplace_cb**) &env->inplace_cb_lists[type];
+ /* append at end of list */
+ while(*prevp != NULL)
+ prevp = &((*prevp)->next);
+ *prevp = callback;
+ return 1;
+}
+
+void
+inplace_cb_delete(struct module_env* env, enum inplace_cb_list_type type,
+ int id)
+{
+ struct inplace_cb* temp = env->inplace_cb_lists[type];
+ struct inplace_cb* prev = NULL;
+
+ while(temp) {
+ if(temp->id == id) {
+ if(!prev) {
+ env->inplace_cb_lists[type] = temp->next;
+ free(temp);
+ temp = env->inplace_cb_lists[type];
+ }
+ else {
+ prev->next = temp->next;
+ free(temp);
+ temp = prev->next;
+ }
+ }
+ else {
+ prev = temp;
+ temp = temp->next;
+ }
+ }
+}
+
+struct edns_known_option*
+edns_option_is_known(uint16_t opt_code, struct module_env* env)
+{
+ size_t i;
+ for(i=0; i<env->edns_known_options_num; i++)
+ if(env->edns_known_options[i].opt_code == opt_code)
+ return env->edns_known_options + i;
+ return NULL;
+}
+
+int
+edns_bypass_cache_stage(struct edns_option* list, struct module_env* env)
+{
+ size_t i;
+ for(; list; list=list->next)
+ for(i=0; i<env->edns_known_options_num; i++)
+ if(env->edns_known_options[i].opt_code == list->opt_code &&
+ env->edns_known_options[i].bypass_cache_stage == 1)
+ return 1;
+ return 0;
+}
+
+int
+unique_mesh_state(struct edns_option* list, struct module_env* env)
+{
+ size_t i;
+ if(env->unique_mesh)
+ return 1;
+ for(; list; list=list->next)
+ for(i=0; i<env->edns_known_options_num; i++)
+ if(env->edns_known_options[i].opt_code == list->opt_code &&
+ env->edns_known_options[i].no_aggregation == 1)
+ return 1;
+ return 0;
+}
+
+void
+log_edns_known_options(enum verbosity_value level, struct module_env* env)
+{
+ size_t i;
+ char str[32], *s;
+ size_t slen;
+ if(env->edns_known_options_num > 0 && verbosity >= level) {
+ verbose(level, "EDNS known options:");
+ verbose(level, " Code: Bypass_cache_stage: Aggregate_mesh:");
+ for(i=0; i<env->edns_known_options_num; i++) {
+ s = str;
+ slen = sizeof(str);
+ (void)sldns_wire2str_edns_option_code_print(&s, &slen,
+ env->edns_known_options[i].opt_code);
+ verbose(level, " %-8.8s %-19s %-15s", str,
+ env->edns_known_options[i].bypass_cache_stage?"YES":"NO",
+ env->edns_known_options[i].no_aggregation?"NO":"YES");
+ }
+ }
+}