summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorStuart Henderson <sthen@cvs.openbsd.org>2020-12-10 21:44:25 +0000
committerStuart Henderson <sthen@cvs.openbsd.org>2020-12-10 21:44:25 +0000
commitc402e6c206d663d512d3fca6dd4ba9cb73df8624 (patch)
treebe055188d400d28e330cc98a2c6f1eaf5bdb3169 /usr.sbin
parent645a38c4ecf4232d68ff57422ab95cc0a9303091 (diff)
import unbound 1.13.0, heavy lifting done by florian@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/unbound/dnstap/dtstream.c8
-rw-r--r--usr.sbin/unbound/services/rpz.c2
-rwxr-xr-xusr.sbin/unbound/testcode/do-tests.sh3
-rw-r--r--usr.sbin/unbound/testcode/dohclient.c136
-rw-r--r--usr.sbin/unbound/testcode/fake_event.c27
-rw-r--r--usr.sbin/unbound/testcode/run_vm.sh2
-rw-r--r--usr.sbin/unbound/testcode/testbound.c4
-rw-r--r--usr.sbin/unbound/testcode/unitmain.c47
-rw-r--r--usr.sbin/unbound/util/edns.c73
-rw-r--r--usr.sbin/unbound/util/edns.h52
-rw-r--r--usr.sbin/unbound/util/regional.c31
-rw-r--r--usr.sbin/unbound/util/regional.h13
12 files changed, 282 insertions, 116 deletions
diff --git a/usr.sbin/unbound/dnstap/dtstream.c b/usr.sbin/unbound/dnstap/dtstream.c
index b0918c52cc6..f1ace3c3402 100644
--- a/usr.sbin/unbound/dnstap/dtstream.c
+++ b/usr.sbin/unbound/dnstap/dtstream.c
@@ -341,15 +341,19 @@ int dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg)
dtio->is_bidirectional = cfg->dnstap_bidirectional;
if(dtio->upstream_is_unix) {
+ char* nm;
if(!cfg->dnstap_socket_path ||
cfg->dnstap_socket_path[0]==0) {
log_err("dnstap setup: no dnstap-socket-path for "
"socket connect");
return 0;
}
+ nm = cfg->dnstap_socket_path;
+ if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm,
+ cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
+ nm += strlen(cfg->chrootdir);
free(dtio->socket_path);
- dtio->socket_path = fname_after_chroot(cfg->dnstap_socket_path,
- cfg, 1);
+ dtio->socket_path = strdup(nm);
if(!dtio->socket_path) {
log_err("dnstap setup: malloc failure");
return 0;
diff --git a/usr.sbin/unbound/services/rpz.c b/usr.sbin/unbound/services/rpz.c
index ba5dd186daa..13304652cc0 100644
--- a/usr.sbin/unbound/services/rpz.c
+++ b/usr.sbin/unbound/services/rpz.c
@@ -440,6 +440,8 @@ err:
respip_set_delete(r->respip_set);
if(r->taglist)
free(r->taglist);
+ if(r->region)
+ regional_destroy(r->region);
free(r);
}
return NULL;
diff --git a/usr.sbin/unbound/testcode/do-tests.sh b/usr.sbin/unbound/testcode/do-tests.sh
index 5439f0f285e..effb7c16a5b 100755
--- a/usr.sbin/unbound/testcode/do-tests.sh
+++ b/usr.sbin/unbound/testcode/do-tests.sh
@@ -29,6 +29,9 @@ else
HAVE_MINGW=no
fi
+# stop tests from notifying systemd, if that is compiled in.
+export -n NOTIFY_SOCKET
+
cd testdata;
sh ../testcode/mini_tdir.sh clean
rm -f .perfstats.txt
diff --git a/usr.sbin/unbound/testcode/dohclient.c b/usr.sbin/unbound/testcode/dohclient.c
index adcc7d83155..263418049be 100644
--- a/usr.sbin/unbound/testcode/dohclient.c
+++ b/usr.sbin/unbound/testcode/dohclient.c
@@ -90,6 +90,7 @@ static void usage(char* argv[])
printf("-e HTTP endpoint, default: /dns-query\n");
printf("-c Content-type in request, default: "
"application/dns-message\n");
+ printf("-n no-tls, TLS is disabled\n");
printf("-h This help text\n");
exit(1);
}
@@ -185,7 +186,10 @@ submit_query(struct http2_session* h2_session, struct sldns_buffer* buf)
headers[1].name = (uint8_t*)":path";
headers[1].value = (uint8_t*)h2_stream->path;
headers[2].name = (uint8_t*)":scheme";
- headers[2].value = (uint8_t*)"https";
+ if(h2_session->ssl)
+ headers[2].value = (uint8_t*)"https";
+ else
+ headers[2].value = (uint8_t*)"http";
headers[3].name = (uint8_t*)":authority";
headers[3].value = (uint8_t*)h2_session->authority;
headers[4].name = (uint8_t*)"content-type";
@@ -246,6 +250,7 @@ static ssize_t http2_recv_cb(nghttp2_session* ATTR_UNUSED(session),
{
struct http2_session* h2_session = (struct http2_session*)cb_arg;
int r;
+ ssize_t ret;
struct timeval tv, *waittv;
fd_set rfd;
ERR_clear_error();
@@ -267,35 +272,58 @@ static ssize_t http2_recv_cb(nghttp2_session* ATTR_UNUSED(session),
return NGHTTP2_ERR_WOULDBLOCK;
}
- r = SSL_read(h2_session->ssl, buf, len);
- if(r <= 0) {
- int want = SSL_get_error(h2_session->ssl, r);
- if(want == SSL_ERROR_ZERO_RETURN) {
+ if(h2_session->ssl) {
+ r = SSL_read(h2_session->ssl, buf, len);
+ if(r <= 0) {
+ int want = SSL_get_error(h2_session->ssl, r);
+ if(want == SSL_ERROR_ZERO_RETURN) {
+ return NGHTTP2_ERR_EOF;
+ }
+ log_crypto_err("could not SSL_read");
return NGHTTP2_ERR_EOF;
}
- log_crypto_err("could not SSL_read");
+ return r;
+ }
+
+ ret = read(h2_session->fd, buf, len);
+ if(ret == 0) {
+ return NGHTTP2_ERR_EOF;
+ } else if(ret < 0) {
+ log_err("could not http2 read: %s", strerror(errno));
return NGHTTP2_ERR_EOF;
}
- return r;
+ return ret;
}
static ssize_t http2_send_cb(nghttp2_session* ATTR_UNUSED(session),
const uint8_t* buf, size_t len, int ATTR_UNUSED(flags), void* cb_arg)
{
struct http2_session* h2_session = (struct http2_session*)cb_arg;
+ ssize_t ret;
- int r;
- ERR_clear_error();
- r = SSL_write(h2_session->ssl, buf, len);
- if(r <= 0) {
- int want = SSL_get_error(h2_session->ssl, r);
- if(want == SSL_ERROR_ZERO_RETURN) {
+ if(h2_session->ssl) {
+ int r;
+ ERR_clear_error();
+ r = SSL_write(h2_session->ssl, buf, len);
+ if(r <= 0) {
+ int want = SSL_get_error(h2_session->ssl, r);
+ if(want == SSL_ERROR_ZERO_RETURN) {
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ }
+ log_crypto_err("could not SSL_write");
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
- log_crypto_err("could not SSL_write");
+ return r;
+ }
+
+ ret = write(h2_session->fd, buf, len);
+ if(ret == 0) {
+ return NGHTTP2_ERR_CALLBACK_FAILURE;
+ } else if(ret < 0) {
+ log_err("could not http2 write: %s", strerror(errno));
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
- return r;
+ return ret;
}
static int http2_stream_close_cb(nghttp2_session* ATTR_UNUSED(session),
@@ -459,7 +487,7 @@ http2_read(struct http2_session* h2_session)
}
static void
-run(struct http2_session* h2_session, int port, int count, char** q)
+run(struct http2_session* h2_session, int port, int no_tls, int count, char** q)
{
int i;
SSL_CTX* ctx = NULL;
@@ -470,26 +498,28 @@ run(struct http2_session* h2_session, int port, int count, char** q)
fd = open_svr(h2_session->authority, port);
h2_session->fd = fd;
- ctx = connect_sslctx_create(NULL, NULL, NULL, 0);
- if(!ctx) fatal_exit("cannot create ssl ctx");
- SSL_CTX_set_alpn_protos(ctx, (const unsigned char *)"\x02h2", 3);
- ssl = outgoing_ssl_fd(ctx, fd);
- if(!ssl) {
- printf("cannot create ssl\n");
- exit(1);
- }
- h2_session->ssl = ssl;
- while(1) {
- int r;
- ERR_clear_error();
- if( (r=SSL_do_handshake(ssl)) == 1)
- break;
- r = SSL_get_error(ssl, r);
- if(r != SSL_ERROR_WANT_READ &&
- r != SSL_ERROR_WANT_WRITE) {
- log_crypto_err("could not ssl_handshake");
+ if(!no_tls) {
+ ctx = connect_sslctx_create(NULL, NULL, NULL, 0);
+ if(!ctx) fatal_exit("cannot create ssl ctx");
+ SSL_CTX_set_alpn_protos(ctx, (const unsigned char *)"\x02h2", 3);
+ ssl = outgoing_ssl_fd(ctx, fd);
+ if(!ssl) {
+ printf("cannot create ssl\n");
exit(1);
}
+ h2_session->ssl = ssl;
+ while(1) {
+ int r;
+ ERR_clear_error();
+ if( (r=SSL_do_handshake(ssl)) == 1)
+ break;
+ r = SSL_get_error(ssl, r);
+ if(r != SSL_ERROR_WANT_READ &&
+ r != SSL_ERROR_WANT_WRITE) {
+ log_crypto_err("could not ssl_handshake");
+ exit(1);
+ }
+ }
}
http2_submit_setting(h2_session);
@@ -511,9 +541,13 @@ run(struct http2_session* h2_session, int port, int count, char** q)
/* shutdown */
http2_session_delete(h2_session);
- SSL_shutdown(ssl);
- SSL_free(ssl);
- SSL_CTX_free(ctx);
+ if(ssl) {
+ SSL_shutdown(ssl);
+ SSL_free(ssl);
+ }
+ if(ctx) {
+ SSL_CTX_free(ctx);
+ }
close(fd);
}
@@ -524,10 +558,21 @@ extern char* optarg;
int main(int argc, char** argv)
{
int c;
- int port = UNBOUND_DNS_OVER_HTTPS_PORT;
- struct http2_session* h2_session = http2_session_create();
- if(!h2_session) fatal_exit("out of memory");
+ int port = UNBOUND_DNS_OVER_HTTPS_PORT, no_tls = 0;
+ struct http2_session* h2_session;
+#ifdef USE_WINSOCK
+ WSADATA wsa_data;
+ if(WSAStartup(MAKEWORD(2,2), &wsa_data) != 0) {
+ printf("WSAStartup failed\n");
+ return 1;
+ }
+#endif
+ log_init(0, 0, 0);
+ checklock_start();
+
+ h2_session = http2_session_create();
+ if(!h2_session) fatal_exit("out of memory");
if(argc == 1) {
usage(argv);
}
@@ -537,7 +582,7 @@ int main(int argc, char** argv)
h2_session->endpoint = "/dns-query";
h2_session->content_type = "application/dns-message";
- while((c=getopt(argc, argv, "c:e:hs:p:P")) != -1) {
+ while((c=getopt(argc, argv, "c:e:hns:p:P")) != -1) {
switch(c) {
case 'c':
h2_session->content_type = optarg;
@@ -545,6 +590,9 @@ int main(int argc, char** argv)
case 'e':
h2_session->endpoint = optarg;
break;
+ case 'n':
+ no_tls = 1;
+ break;
case 'p':
if(atoi(optarg)==0 && strcmp(optarg,"0")!=0) {
printf("error parsing port, "
@@ -573,8 +621,12 @@ int main(int argc, char** argv)
}
- run(h2_session, port, argc, argv);
+ run(h2_session, port, no_tls, argc, argv);
+ checklock_stop();
+#ifdef USE_WINSOCK
+ WSACleanup();
+#endif
return 0;
}
#else
diff --git a/usr.sbin/unbound/testcode/fake_event.c b/usr.sbin/unbound/testcode/fake_event.c
index d8df7649254..591557c35f1 100644
--- a/usr.sbin/unbound/testcode/fake_event.c
+++ b/usr.sbin/unbound/testcode/fake_event.c
@@ -872,6 +872,7 @@ listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports),
int ATTR_UNUSED(harden_large_queries),
uint32_t ATTR_UNUSED(http_max_streams),
char* ATTR_UNUSED(http_endpoint),
+ int ATTR_UNUSED(http_notls),
struct tcl_list* ATTR_UNUSED(tcp_conn_limit),
void* ATTR_UNUSED(sslctx), struct dt_env* ATTR_UNUSED(dtenv),
comm_point_callback_type* cb, void *cb_arg)
@@ -1044,7 +1045,7 @@ outside_network_create(struct comm_base* base, size_t bufsize,
void (*unwanted_action)(void*), void* ATTR_UNUSED(unwanted_param),
int ATTR_UNUSED(do_udp), void* ATTR_UNUSED(sslctx),
int ATTR_UNUSED(delayclose), int ATTR_UNUSED(tls_use_sni),
- struct dt_env* ATTR_UNUSED(dtenv))
+ struct dt_env* ATTR_UNUSED(dtenv), int ATTR_UNUSED(udp_connect))
{
struct replay_runtime* runtime = (struct replay_runtime*)base;
struct outside_network* outnet = calloc(1,
@@ -1213,7 +1214,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
sldns_buffer_flip(pend->buffer);
if(1) {
struct edns_data edns;
- struct edns_tag_addr* client_tag_addr;
+ struct edns_string_addr* client_string_addr;
if(!inplace_cb_query_call(env, qinfo, flags, addr, addrlen,
zone, zonelen, qstate, qstate->region)) {
free(pend);
@@ -1227,13 +1228,13 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
edns.bits = 0;
if(dnssec)
edns.bits = EDNS_DO;
- if((client_tag_addr = edns_tag_addr_lookup(
- &env->edns_tags->client_tags,
+ if((client_string_addr = edns_string_addr_lookup(
+ &env->edns_strings->client_strings,
addr, addrlen))) {
- uint16_t client_tag = htons(client_tag_addr->tag_data);
edns_opt_list_append(&qstate->edns_opts_back_out,
- env->edns_tags->client_tag_opcode, 2,
- (uint8_t*)&client_tag, qstate->region);
+ env->edns_strings->client_string_opcode,
+ client_string_addr->string_len,
+ client_string_addr->string, qstate->region);
}
edns.opt_list = qstate->edns_opts_back_out;
attach_edns_record(pend->buffer, &edns);
@@ -1510,6 +1511,18 @@ int serviced_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
return 0;
}
+int reuse_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
+{
+ log_assert(0);
+ return 0;
+}
+
+int reuse_id_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
+{
+ log_assert(0);
+ return 0;
+}
+
/* timers in testbound for autotrust. statistics tested in tdir. */
struct comm_timer* comm_timer_create(struct comm_base* base,
void (*cb)(void*), void* cb_arg)
diff --git a/usr.sbin/unbound/testcode/run_vm.sh b/usr.sbin/unbound/testcode/run_vm.sh
index 5f599e144a5..363a32b52cb 100644
--- a/usr.sbin/unbound/testcode/run_vm.sh
+++ b/usr.sbin/unbound/testcode/run_vm.sh
@@ -40,6 +40,8 @@ cleanup() {
exit 0
}
trap cleanup INT
+# stop tests from notifying systemd, if that is compiled in.
+export -n NOTIFY_SOCKET
for t in $RUNLIST
do
diff --git a/usr.sbin/unbound/testcode/testbound.c b/usr.sbin/unbound/testcode/testbound.c
index 602dffaff14..3f3e106b039 100644
--- a/usr.sbin/unbound/testcode/testbound.c
+++ b/usr.sbin/unbound/testcode/testbound.c
@@ -362,6 +362,10 @@ main(int argc, char* argv[])
/* we do not want the test to depend on the timezone */
(void)putenv("TZ=UTC");
memset(pass_argv, 0, sizeof(pass_argv));
+#ifdef HAVE_SYSTEMD
+ /* we do not want the test to use systemd daemon startup notification*/
+ (void)unsetenv("NOTIFY_SOCKET");
+#endif /* HAVE_SYSTEMD */
log_init(NULL, 0, NULL);
/* determine commandline options for the daemon */
diff --git a/usr.sbin/unbound/testcode/unitmain.c b/usr.sbin/unbound/testcode/unitmain.c
index a42be424e9e..c61026f2680 100644
--- a/usr.sbin/unbound/testcode/unitmain.c
+++ b/usr.sbin/unbound/testcode/unitmain.c
@@ -839,6 +839,52 @@ static void respip_test(void)
respip_conf_actions_test();
}
+#include "services/outside_network.h"
+/** add number of new IDs to the reuse tree, randomly chosen */
+static void tcpid_addmore(struct reuse_tcp* reuse,
+ struct outside_network* outnet, unsigned int addnum)
+{
+ unsigned int i;
+ struct waiting_tcp* w;
+ for(i=0; i<addnum; i++) {
+ uint16_t id = reuse_tcp_select_id(reuse, outnet);
+ unit_assert(!reuse_tcp_by_id_find(reuse, id));
+ w = calloc(1, sizeof(*w));
+ unit_assert(w);
+ w->id = id;
+ w->outnet = outnet;
+ w->next_waiting = (void*)reuse->pending;
+ reuse_tree_by_id_insert(reuse, w);
+ }
+}
+
+/** fill up the reuse ID tree and test assertions */
+static void tcpid_fillup(struct reuse_tcp* reuse,
+ struct outside_network* outnet)
+{
+ int t, numtest=3;
+ for(t=0; t<numtest; t++) {
+ rbtree_init(&reuse->tree_by_id, reuse_id_cmp);
+ tcpid_addmore(reuse, outnet, 65535);
+ reuse_del_readwait(&reuse->tree_by_id);
+ }
+}
+
+/** test TCP ID selection */
+static void tcpid_test(void)
+{
+ struct pending_tcp pend;
+ struct outside_network outnet;
+ unit_show_func("services/outside_network.c", "reuse_tcp_select_id");
+ memset(&pend, 0, sizeof(pend));
+ pend.reuse.pending = &pend;
+ memset(&outnet, 0, sizeof(outnet));
+ outnet.rnd = ub_initstate(NULL);
+ rbtree_init(&pend.reuse.tree_by_id, reuse_id_cmp);
+ tcpid_fillup(&pend.reuse, &outnet);
+ ub_randfree(outnet.rnd);
+}
+
void unit_show_func(const char* file, const char* func)
{
printf("test %s:%s\n", file, func);
@@ -907,6 +953,7 @@ main(int argc, char* argv[])
infra_test();
ldns_test();
msgparse_test();
+ tcpid_test();
#ifdef CLIENT_SUBNET
ecs_test();
#endif /* CLIENT_SUBNET */
diff --git a/usr.sbin/unbound/util/edns.c b/usr.sbin/unbound/util/edns.c
index c83a4a545fe..ddbb46e892c 100644
--- a/usr.sbin/unbound/util/edns.c
+++ b/usr.sbin/unbound/util/edns.c
@@ -48,81 +48,84 @@
#include "util/data/msgparse.h"
#include "util/data/msgreply.h"
-struct edns_tags* edns_tags_create(void)
+struct edns_strings* edns_strings_create(void)
{
- struct edns_tags* edns_tags = calloc(1, sizeof(struct edns_tags));
- if(!edns_tags)
+ struct edns_strings* edns_strings = calloc(1,
+ sizeof(struct edns_strings));
+ if(!edns_strings)
return NULL;
- if(!(edns_tags->region = regional_create())) {
- edns_tags_delete(edns_tags);
+ if(!(edns_strings->region = regional_create())) {
+ edns_strings_delete(edns_strings);
return NULL;
}
- return edns_tags;
+ return edns_strings;
}
-void edns_tags_delete(struct edns_tags* edns_tags)
+void edns_strings_delete(struct edns_strings* edns_strings)
{
- if(!edns_tags)
+ if(!edns_strings)
return;
- regional_destroy(edns_tags->region);
- free(edns_tags);
+ regional_destroy(edns_strings->region);
+ free(edns_strings);
}
static int
-edns_tags_client_insert(struct edns_tags* edns_tags,
+edns_strings_client_insert(struct edns_strings* edns_strings,
struct sockaddr_storage* addr, socklen_t addrlen, int net,
- uint16_t tag_data)
+ const char* string)
{
- struct edns_tag_addr* eta = regional_alloc_zero(edns_tags->region,
- sizeof(struct edns_tag_addr));
- if(!eta)
+ struct edns_string_addr* esa = regional_alloc_zero(edns_strings->region,
+ sizeof(struct edns_string_addr));
+ if(!esa)
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.");
+ esa->string_len = strlen(string);
+ esa->string = regional_alloc_init(edns_strings->region, string,
+ esa->string_len);
+ if(!esa->string)
+ return 0;
+ if(!addr_tree_insert(&edns_strings->client_strings, &esa->node, addr,
+ addrlen, net)) {
+ verbose(VERB_QUERY, "duplicate EDNS client string ignored.");
}
return 1;
}
-int edns_tags_apply_cfg(struct edns_tags* edns_tags,
+int edns_strings_apply_cfg(struct edns_strings* edns_strings,
struct config_file* config)
{
struct config_str2list* c;
- regional_free_all(edns_tags->region);
- addr_tree_init(&edns_tags->client_tags);
+ regional_free_all(edns_strings->region);
+ addr_tree_init(&edns_strings->client_strings);
- for(c=config->edns_client_tags; c; c=c->next) {
+ for(c=config->edns_client_strings; 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);
+ log_err("cannot parse EDNS client string 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");
+ if(!edns_strings_client_insert(edns_strings, &addr, addrlen,
+ net, c->str2)) {
+ log_err("out of memory while adding EDNS strings");
return 0;
}
}
- edns_tags->client_tag_opcode = config->edns_client_tag_opcode;
+ edns_strings->client_string_opcode = config->edns_client_string_opcode;
- addr_tree_init_parents(&edns_tags->client_tags);
+ addr_tree_init_parents(&edns_strings->client_strings);
return 1;
}
-struct edns_tag_addr*
-edns_tag_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr,
+struct edns_string_addr*
+edns_string_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_string_addr*)addr_tree_lookup(tree, addr, addrlen);
}
static int edns_keepalive(struct edns_data* edns_out, struct edns_data* edns_in,
diff --git a/usr.sbin/unbound/util/edns.h b/usr.sbin/unbound/util/edns.h
index cf9f8707e80..11742eb5b72 100644
--- a/usr.sbin/unbound/util/edns.h
+++ b/usr.sbin/unbound/util/edns.h
@@ -50,58 +50,60 @@ struct comm_point;
struct regional;
/**
- * Structure containing all EDNS tags.
+ * Structure containing all EDNS strings.
*/
-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;
- /** EDNS opcode to use for client tags */
- uint16_t client_tag_opcode;
+struct edns_strings {
+ /** Tree of EDNS client strings to use in upstream queries, per address
+ * prefix. Contains nodes of type edns_string_addr. */
+ rbtree_type client_strings;
+ /** EDNS opcode to use for client strings */
+ uint16_t client_string_opcode;
/** region to allocate tree nodes in */
struct regional* region;
};
/**
- * EDNS tag. Node of rbtree, containing tag and prefix.
+ * EDNS string. Node of rbtree, containing string and prefix.
*/
-struct edns_tag_addr {
+struct edns_string_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;
+ /** string, ascii format */
+ uint8_t* string;
+ /** length of string */
+ size_t string_len;
};
/**
- * Create structure to hold EDNS tags
- * @return: newly created edns_tags, NULL on alloc failure.
+ * Create structure to hold EDNS strings
+ * @return: newly created edns_strings, NULL on alloc failure.
*/
-struct edns_tags* edns_tags_create(void);
+struct edns_strings* edns_strings_create(void);
-/** Delete EDNS tags structure
- * @param edns_tags: struct to delete
+/** Delete EDNS strings structure
+ * @param edns_strings: struct to delete
*/
-void edns_tags_delete(struct edns_tags* edns_tags);
+void edns_strings_delete(struct edns_strings* edns_strings);
/**
- * Add configured EDNS tags
- * @param edns_tags: edns tags to apply config to
- * @param config: struct containing EDNS tags configuration
+ * Add configured EDNS strings
+ * @param edns_strings: edns strings to apply config to
+ * @param config: struct containing EDNS strings configuration
* @return 0 on error
*/
-int edns_tags_apply_cfg(struct edns_tags* edns_tags,
+int edns_strings_apply_cfg(struct edns_strings* edns_strings,
struct config_file* config);
/**
- * Find tag for address.
- * @param tree: tree containing EDNS tags per address prefix.
+ * Find string for address.
+ * @param tree: tree containing EDNS strings 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,
+struct edns_string_addr*
+edns_string_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr,
socklen_t addrlen);
/**
diff --git a/usr.sbin/unbound/util/regional.c b/usr.sbin/unbound/util/regional.c
index ff36d0e2124..bd67ecf50af 100644
--- a/usr.sbin/unbound/util/regional.c
+++ b/usr.sbin/unbound/util/regional.c
@@ -80,18 +80,39 @@ regional_init(struct regional* r)
r->total_large = 0;
}
-struct regional*
-regional_create_custom(size_t size)
+/**
+ * Create a new region, with custom first block and large-object sizes.
+ * @param size: length of first block.
+ * @param large_object_size: outside of chunk allocation threshold.
+ * @return: newly allocated regional.
+ */
+static struct regional*
+regional_create_custom_large_object(size_t size, size_t large_object_size)
{
- struct regional* r = (struct regional*)malloc(size);
+ struct regional* r;
size = ALIGN_UP(size, ALIGNMENT);
+ r = (struct regional*)malloc(size);
log_assert(sizeof(struct regional) <= size);
if(!r) return NULL;
r->first_size = size;
+ r->large_object_size = large_object_size;
regional_init(r);
return r;
}
+struct regional*
+regional_create_custom(size_t size)
+{
+ return regional_create_custom_large_object(size,
+ REGIONAL_LARGE_OBJECT_SIZE);
+}
+
+struct regional*
+regional_create_nochunk(size_t size)
+{
+ return regional_create_custom_large_object(size, 0);
+}
+
void
regional_free_all(struct regional *r)
{
@@ -134,7 +155,7 @@ regional_alloc(struct regional *r, size_t size)
malloc and ALIGN_UP */
a = ALIGN_UP(size, ALIGNMENT);
/* large objects */
- if(a > REGIONAL_LARGE_OBJECT_SIZE) {
+ if(a > r->large_object_size) {
s = malloc(ALIGNMENT + size);
if(!s) return NULL;
r->total_large += ALIGNMENT+size;
@@ -219,7 +240,7 @@ regional_log_stats(struct regional *r)
/* some basic assertions put here (non time critical code) */
log_assert(ALIGNMENT >= sizeof(char*));
log_assert(REGIONAL_CHUNK_SIZE > ALIGNMENT);
- log_assert(REGIONAL_CHUNK_SIZE-ALIGNMENT > REGIONAL_LARGE_OBJECT_SIZE);
+ log_assert(REGIONAL_CHUNK_SIZE-ALIGNMENT > r->large_object_size);
log_assert(REGIONAL_CHUNK_SIZE >= sizeof(struct regional));
/* debug print */
log_info("regional %u chunks, %u large",
diff --git a/usr.sbin/unbound/util/regional.h b/usr.sbin/unbound/util/regional.h
index e8b2cb8d00c..b439897d52e 100644
--- a/usr.sbin/unbound/util/regional.h
+++ b/usr.sbin/unbound/util/regional.h
@@ -74,6 +74,11 @@ struct regional
size_t available;
/** current chunk data position. */
char* data;
+ /** threshold for outside of chunk allocations */
+ size_t large_object_size;
+ /** padding for sizeof8 alignment of sizeof(struct regional)
+ * for 32bit systems */
+ size_t padding;
};
/**
@@ -88,6 +93,14 @@ struct regional* regional_create(void);
* @return: newly allocated regional.
*/
struct regional* regional_create_custom(size_t size);
+
+/**
+ * Create a new region, with custom settings, that will allocate everything
+ * outside the region chunk.
+ * @param size: length of first block.
+ * @return: newly allocated regional.
+ */
+struct regional* regional_create_nochunk(size_t size);
/**
* Free all memory associated with regional. Only keeps the first block with