#include "util/storage/lookup3.h"
#include "util/storage/slabhash.h"
#include "util/tcp_conn_limit.h"
+#include "util/edns.h"
#include "services/listen_dnsport.h"
#include "services/cache/rrset.h"
#include "services/cache/infra.h"
free(daemon);
return NULL;
}
+ if(!(daemon->env->edns_tags = edns_tags_create())) {
+ auth_zones_delete(daemon->env->auth_zones);
+ acl_list_delete(daemon->acl);
+ tcl_list_delete(daemon->tcl);
+ edns_known_options_delete(daemon->env);
+ free(daemon->env);
+ free(daemon);
+ return NULL;
+ }
return daemon;
}
&daemon->use_rpz))
fatal_exit("auth_zones could not be setup");
+ /* Set-up EDNS tags */
+ if(!edns_tags_apply_cfg(daemon->env->edns_tags, daemon->cfg))
+ fatal_exit("Could not set up EDNS tags");
+
/* setup modules */
daemon_setup_modules(daemon);
rrset_cache_delete(daemon->env->rrset_cache);
infra_delete(daemon->env->infra_cache);
edns_known_options_delete(daemon->env);
+ edns_tags_delete(daemon->env->edns_tags);
auth_zones_delete(daemon->env->auth_zones);
}
ub_randfree(daemon->rand);
#include "util/net_help.h"
#include "util/random.h"
#include "util/fptr_wlist.h"
+#include "util/edns.h"
#include "sldns/sbuffer.h"
#include "dnstap/dnstap.h"
#ifdef HAVE_OPENSSL_SSL_H
{
struct serviced_query* sq;
struct service_callback* cb;
+ struct edns_tag_addr* client_tag_addr;
+
if(!inplace_cb_query_call(env, qinfo, flags, addr, addrlen, zone, zonelen,
qstate, qstate->region))
return NULL;
+
+ 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,
+ LDNS_EDNS_CLIENT_TAG, 2,
+ (uint8_t*)&client_tag, qstate->region);
+ }
+
serviced_gen_query(buff, qinfo->qname, qinfo->qname_len, qinfo->qtype,
qinfo->qclass, flags);
sq = lookup_serviced(outnet, buff, dnssec, addr, addrlen,
LDNS_EDNS_N3U = 7, /* RFC6975 */
LDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
LDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/
- LDNS_EDNS_PADDING = 12 /* RFC7830 */
+ LDNS_EDNS_PADDING = 12, /* RFC7830 */
+ LDNS_EDNS_CLIENT_TAG = 16 /* draft-bellis-dnsop-edns-tags-01 */
};
typedef enum sldns_enum_edns_option sldns_edns_option;
#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);
+}
+
+int edns_tags_apply_cfg(struct edns_tags* edns_tags,
+ struct config_file* config)
+{
+ regional_free_all(edns_tags->region);
+ addr_tree_init(&edns_tags->client_tags);
+
+ /* TODO walk over config, create and insert node. */
+
+ 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)
{
#ifndef UTIL_EDNS_H
#define UTIL_EDNS_H
+#include "util/storage/dnstree.h"
+
struct edns_data;
struct config_file;
struct comm_point;
struct regional;
+/**
+ * Structure containing all EDNS tags.
+ */
+struct edns_tags {
+ /** Tree of EDNS client tags to use in upstream queries, per address
+ * prefix. Contains nodes of type edns_tag_addr. */
+ rbtree_type client_tags;
+ /** region to allocate tree nodes in */
+ struct regional* region;
+};
+
+/**
+ * EDNS tag. Node of rbtree, containing tag and prefix.
+ */
+struct edns_tag_addr {
+ /** node in address tree, used for tree lookups. Need to be the first
+ * member of this struct. */
+ struct addr_tree_node node;
+ /** tag data, in host byte ordering */
+ uint16_t tag_data;
+};
+
+/**
+ * Create structure to hold EDNS tags
+ * @return: newly created edns_tags, NULL on alloc failure.
+ */
+struct edns_tags* edns_tags_create(void);
+
+/** Delete ENDS tags structure
+ * @param edns_tags: struct to delete
+ */
+void edns_tags_delete(struct edns_tags* edns_tags);
+
+/**
+ * Add configured EDNS tags
+ * @param edns_tags: edns tags to apply config to
+ * @param config: struct containing EDNS tags configuration
+ * @return 0 on error
+ */
+int edns_tags_apply_cfg(struct edns_tags* edns_tags,
+ struct config_file* config);
+
+/**
+ * Find tag for address.
+ * @param tree: tree containing EDNS tags per address prefix.
+ * @param addr: address to use for tree lookup
+ * @param addrlen: length of address
+ * @return: matching tree node, NULL otherwise
+ */
+struct edns_tag_addr*
+edns_tag_addr_lookup(rbtree_type tree, struct sockaddr_storage* addr,
+ socklen_t addrlen);
+
/**
* Apply common EDNS options.
*
struct edns_known_option* edns_known_options;
/* Number of known edns options */
size_t edns_known_options_num;
+ struct edns_tags* edns_tags;
/* Make every mesh state unique, do not aggregate mesh states. */
int unique_mesh;