]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
EDNS client tags - insert configured tags into tree
authorRalph Dolmans <ralph@nlnetlabs.nl>
Fri, 24 Jul 2020 14:00:13 +0000 (16:00 +0200)
committerRalph Dolmans <ralph@nlnetlabs.nl>
Fri, 24 Jul 2020 14:00:13 +0000 (16:00 +0200)
services/outside_network.c
util/edns.c
util/edns.h

index b7ac5ef60b6ef7ff0f09a2e430e7d1eecf6d3116..67eca05ed7ba55c515ed82e54cf284d1fddcc3d9 100644 (file)
@@ -2118,7 +2118,7 @@ outnet_serviced_query(struct outside_network* outnet,
                qstate, qstate->region))
                        return NULL;
 
-       if((client_tag_addr = edns_tag_addr_lookup(env->edns_tags->client_tags,
+       if((client_tag_addr = edns_tag_addr_lookup(&env->edns_tags->client_tags,
                addr, addrlen))) {
                uint16_t client_tag = htons(client_tag_addr->tag_data);
                edns_opt_list_append(&qstate->edns_opts_back_out,
index 341b7f90af2616d1a42191afb63fa67db2b9683b..db33212c0597676d852dda6f0174ea016f2d732d 100644 (file)
@@ -43,6 +43,7 @@
 #include "util/edns.h"
 #include "util/config_file.h"
 #include "util/netevent.h"
+#include "util/net_help.h"
 #include "util/regional.h"
 #include "util/data/msgparse.h"
 #include "util/data/msgreply.h"
@@ -67,23 +68,60 @@ void edns_tags_delete(struct edns_tags* edns_tags)
        free(edns_tags);
 }
 
+static int
+edns_tags_client_insert(struct edns_tags* edns_tags,
+       struct sockaddr_storage* addr, socklen_t addrlen, int net,
+       uint16_t tag_data)
+{
+       struct edns_tag_addr* eta = regional_alloc_zero(edns_tags->region,
+               sizeof(struct edns_tag_addr));
+       if(!eta)
+               return 0;
+       eta->tag_data = tag_data;
+       if(!addr_tree_insert(&edns_tags->client_tags, &eta->node, addr, addrlen,
+               net)) {
+               verbose(VERB_QUERY, "duplicate EDNS client tag ignored.");
+       }
+       return 1;
+}
+
 int edns_tags_apply_cfg(struct edns_tags* edns_tags,
        struct config_file* config)
 {
+       struct config_str2list* c;
        regional_free_all(edns_tags->region);
        addr_tree_init(&edns_tags->client_tags);
 
-       /* TODO walk over config, create and insert node. */
+       for(c=config->edns_client_tags; c; c=c->next) {
+               struct sockaddr_storage addr;
+               socklen_t addrlen;
+               int net;
+               uint16_t tag_data;
+               log_assert(c->str && c->str2);
+
+               if(!netblockstrtoaddr(c->str, UNBOUND_DNS_PORT, &addr, &addrlen,
+                       &net)) {
+                       log_err("cannot parse EDNS client tag IP netblock: %s",
+                               c->str);
+                       return 0;
+               }
+               tag_data = atoi(c->str2); /* validated in config parser */
+               if(!edns_tags_client_insert(edns_tags, &addr, addrlen, net,
+                       tag_data)) {
+                       log_err("out of memory while adding EDNS tags");
+                       return 0;
+               }
+       }
 
        addr_tree_init_parents(&edns_tags->client_tags);
        return 1;
 }
 
 struct edns_tag_addr*
-edns_tag_addr_lookup(rbtree_type tree, struct sockaddr_storage* addr,
+edns_tag_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr,
        socklen_t addrlen)
 {
-       return (struct edns_tag_addr*)addr_tree_lookup(&tree, addr, addrlen);
+       return (struct edns_tag_addr*)addr_tree_lookup(tree, addr, addrlen);
 }
 
 static int edns_keepalive(struct edns_data* edns_out, struct edns_data* edns_in,
index 310ba1cd2c9f49d0fa93142aa1dba103f25cb266..ee0e3de54e9ea4d883a05d9f125add8b8164047b 100644 (file)
@@ -99,7 +99,7 @@ int edns_tags_apply_cfg(struct edns_tags* edns_tags,
  * @return: matching tree node, NULL otherwise
  */
 struct edns_tag_addr*
-edns_tag_addr_lookup(rbtree_type tree, struct sockaddr_storage* addr,
+edns_tag_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr,
        socklen_t addrlen);
 
 /**