diff options
author | Cy Schubert <cy@FreeBSD.org> | 2020-10-27 15:09:16 +0000 |
---|---|---|
committer | Cy Schubert <cy@FreeBSD.org> | 2020-10-27 15:09:16 +0000 |
commit | 4cb89f2eee3bb358f0491932ab0498b5319f4229 (patch) | |
tree | fc2691469564e7d7e552247f2b2c6e04dd7efb8a /util/edns.c | |
parent | 7973006f41cdaf144441d1a39f9f075053435e2f (diff) | |
download | src-4cb89f2eee3bb358f0491932ab0498b5319f4229.tar.gz src-4cb89f2eee3bb358f0491932ab0498b5319f4229.zip |
Vendor import of Unbound 1.12.0.vendor/unbound/1.12.0
Notes
Notes:
svn path=/vendor/unbound/dist/; revision=367082
svn path=/vendor/unbound/1.12.0/; revision=367083; tag=vendor/unbound/1.12.0
Diffstat (limited to 'util/edns.c')
-rw-r--r-- | util/edns.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/util/edns.c b/util/edns.c index d19952df0946..c83a4a545fe3 100644 --- a/util/edns.c +++ b/util/edns.c @@ -43,10 +43,88 @@ #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" +struct edns_tags* edns_tags_create(void) +{ + struct edns_tags* edns_tags = calloc(1, sizeof(struct edns_tags)); + if(!edns_tags) + return NULL; + if(!(edns_tags->region = regional_create())) { + edns_tags_delete(edns_tags); + return NULL; + } + return edns_tags; +} + +void edns_tags_delete(struct edns_tags* edns_tags) +{ + if(!edns_tags) + return; + regional_destroy(edns_tags->region); + 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); + + 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; + } + } + edns_tags->client_tag_opcode = config->edns_client_tag_opcode; + + 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, + socklen_t 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, struct comm_point* c, struct regional* region) { |