diff options
author | Stuart Henderson <sthen@cvs.openbsd.org> | 2020-12-10 21:44:25 +0000 |
---|---|---|
committer | Stuart Henderson <sthen@cvs.openbsd.org> | 2020-12-10 21:44:25 +0000 |
commit | c402e6c206d663d512d3fca6dd4ba9cb73df8624 (patch) | |
tree | be055188d400d28e330cc98a2c6f1eaf5bdb3169 /usr.sbin | |
parent | 645a38c4ecf4232d68ff57422ab95cc0a9303091 (diff) |
import unbound 1.13.0, heavy lifting done by florian@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/unbound/dnstap/dtstream.c | 8 | ||||
-rw-r--r-- | usr.sbin/unbound/services/rpz.c | 2 | ||||
-rwxr-xr-x | usr.sbin/unbound/testcode/do-tests.sh | 3 | ||||
-rw-r--r-- | usr.sbin/unbound/testcode/dohclient.c | 136 | ||||
-rw-r--r-- | usr.sbin/unbound/testcode/fake_event.c | 27 | ||||
-rw-r--r-- | usr.sbin/unbound/testcode/run_vm.sh | 2 | ||||
-rw-r--r-- | usr.sbin/unbound/testcode/testbound.c | 4 | ||||
-rw-r--r-- | usr.sbin/unbound/testcode/unitmain.c | 47 | ||||
-rw-r--r-- | usr.sbin/unbound/util/edns.c | 73 | ||||
-rw-r--r-- | usr.sbin/unbound/util/edns.h | 52 | ||||
-rw-r--r-- | usr.sbin/unbound/util/regional.c | 31 | ||||
-rw-r--r-- | usr.sbin/unbound/util/regional.h | 13 |
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 |