diff --git a/daemon/daemon.c b/daemon/daemon.c index f882bb9ad..a9cc25c67 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -558,9 +558,11 @@ daemon_create_workers(struct daemon* daemon) verbose(VERB_ALGO, "total of %d outgoing ports available", numport); #ifdef HAVE_NGTCP2 - daemon->doq_table = doq_table_create(daemon->cfg, daemon->rand); - if(!daemon->doq_table) - fatal_exit("could not create doq_table: out of memory"); + if (cfg_has_quic(daemon->cfg)) { + daemon->doq_table = doq_table_create(daemon->cfg, daemon->rand); + if(!daemon->doq_table) + fatal_exit("could not create doq_table: out of memory"); + } #endif daemon->num = (daemon->cfg->num_threads?daemon->cfg->num_threads:1); @@ -917,8 +919,10 @@ daemon_cleanup(struct daemon* daemon) daemon->dnscenv = NULL; #endif #ifdef HAVE_NGTCP2 - doq_table_delete(daemon->doq_table); - daemon->doq_table = NULL; + if (daemon->doq_table) { + doq_table_delete(daemon->doq_table); + daemon->doq_table = NULL; + } #endif daemon->cfg = NULL; } diff --git a/doc/Changelog b/doc/Changelog index 704424cf7..62e3089d1 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,31 @@ +8 January 2026: Wouter + - Merge #1381: Do not initialize quic_table unless it is enabled. + +6 January 2026: Wouter + - Fix edns subnet, that scope zero queries, when there is a + subquery without subnet, and the forward-no-cache or + stub-no-cache option is set, it is not stored in cache due to + the forward or stub option. + +6 January 2026: Yorgos + - Merge #1391 from Götz Görisch: Fix documentation to adhere to + RFC5952. + +31 December 2025: Yorgos + - Update the unbound-anchor man page to note write permissions of the + generated file if it is to be used with Unbound's + auto-trust-anchor-file option. + - Use the same EDE removal logic when encoding errors as when encoding + replies. + +30 December 2025: Yorgos + - Mark "THROWAWAY" and "(DNSSEC) LAME" responses clearly as Unbound's + categorization in the log output. + +24 December 2025: Yorgos + - More specific wording in the unbound.conf man page for stub-first + and forward-first options. + 3 December 2025: Wouter - Fix http2 drop handling to clear the postpone_drop state so that other streams on the http2 session are not affected by a drop, diff --git a/doc/README.DNS64 b/doc/README.DNS64 index 71e2310ed..2f2484434 100644 --- a/doc/README.DNS64 +++ b/doc/README.DNS64 @@ -13,7 +13,7 @@ If you're not using DNSSEC then you may remove "validator". 2. The "dns64-prefix" directive indicates your DNS64 prefix. For example: - dns64-prefix: 64:FF9B::/96 + dns64-prefix: 64:ff9b::/96 The prefix must be a /96 or shorter. @@ -42,9 +42,9 @@ To enable NAT64 in Unbound, add to unbound.conf's "server" section: do-nat64: yes The NAT64 prefix defaults to the DNS64 prefix, which in turn defaults to the -standard 64:FF9B::/96 prefix. You can reconfigure it with: +standard 64:ff9b::/96 prefix. You can reconfigure it with: - nat64-prefix: 64:FF9B::/96 + nat64-prefix: 64:ff9b::/96 To test NAT64 operation, pick a domain that only has IPv4 reachability for its nameservers and try resolving any names in that domain. diff --git a/doc/example.conf.in b/doc/example.conf.in index 296dabbd2..b31a26134 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -54,7 +54,7 @@ server: # interface: 192.0.2.153 # interface: 192.0.2.154 # interface: 192.0.2.154@5003 - # interface: 2001:DB8::5 + # interface: 2001:db8::5 # interface: eth0@5003 # enable this feature to copy the source address of queries to reply. @@ -72,12 +72,12 @@ server: # server from by ip-address. If none, the default (all) interface # is used. Specify every interface on a 'outgoing-interface:' line. # outgoing-interface: 192.0.2.153 - # outgoing-interface: 2001:DB8::5 - # outgoing-interface: 2001:DB8::6 + # outgoing-interface: 2001:db8::5 + # outgoing-interface: 2001:db8::6 # Specify a netblock to use remainder 64 bits as random bits for # upstream queries. Uses freebind option (Linux). - # outgoing-interface: 2001:DB8::/64 + # outgoing-interface: 2001:db8::/64 # Also (Linux:) ip -6 addr add 2001:db8::/64 dev lo # And: ip -6 route add local 2001:db8::/64 dev lo # And set prefer-ip6: yes to use the ip6 randomness from a netblock. @@ -379,7 +379,7 @@ server: # interface-action: 192.0.2.153 allow # interface-action: 192.0.2.154 allow # interface-action: 192.0.2.154@5003 allow - # interface-action: 2001:DB8::5 allow + # interface-action: 2001:db8::5 allow # interface-action: eth0@5003 allow # Similar to 'access-control-tag:' but for interfaces. diff --git a/doc/unbound-anchor.8.in b/doc/unbound-anchor.8.in index 9c77b4cf7..5c8c02fef 100644 --- a/doc/unbound-anchor.8.in +++ b/doc/unbound-anchor.8.in @@ -39,9 +39,17 @@ unbound-anchor \- Unbound @version@ anchor utility. validation. The program fetches the trust anchor with the method from \fI\%RFC 7958\fP when regular \fI\%RFC 5011\fP update fails to bring it up to date. -It can be run (as root) from the commandline, or run as part of startup -scripts. -Before you start the \fI\%unbound(8)\fP DNS server. +It can be run from the commandline, or run as part of startup scripts before +you start the \fI\%unbound(8)\fP DNS server. +.sp +Note that if you want to use \fI\%RFC 5011\fP with Unbound (i.e., the +\fI\%auto\-trust\-anchor\-file\fP option) so +that trust anchor information is automatically tracked by Unbound during +operation, the user that Unbound runs under (by default \(aqunbound\(aq) must have +write permissions to the file and the directory the file lives in (for creating +temporary files). +In this case you would probably want to run this program as the designated +Unbound user. .sp Suggested usage: .INDENT 0.0 @@ -52,6 +60,7 @@ Suggested usage: # in the init scripts. # provide or update the root anchor (if necessary) unbound\-anchor \-a \(dq@UNBOUND_ROOTKEY_FILE@\(dq + # Please note usage of this root anchor is at your own risk # and under the terms of our LICENSE (see source). # diff --git a/doc/unbound-anchor.rst b/doc/unbound-anchor.rst index 480db8eeb..fec351a97 100644 --- a/doc/unbound-anchor.rst +++ b/doc/unbound-anchor.rst @@ -51,9 +51,17 @@ Description validation. The program fetches the trust anchor with the method from :rfc:`7958` when regular :rfc:`5011` update fails to bring it up to date. -It can be run (as root) from the commandline, or run as part of startup -scripts. -Before you start the :doc:`unbound(8)` DNS server. +It can be run from the commandline, or run as part of startup scripts before +you start the :doc:`unbound(8)` DNS server. + +Note that if you want to use :rfc:`5011` with Unbound (i.e., the +:ref:`auto-trust-anchor-file` option) so +that trust anchor information is automatically tracked by Unbound during +operation, the user that Unbound runs under (by default 'unbound') must have +write permissions to the file and the directory the file lives in (for creating +temporary files). +In this case you would probably want to run this program as the designated +Unbound user. Suggested usage: @@ -62,6 +70,7 @@ Suggested usage: # in the init scripts. # provide or update the root anchor (if necessary) unbound-anchor -a "@UNBOUND_ROOTKEY_FILE@" + # Please note usage of this root anchor is at your own risk # and under the terms of our LICENSE (see source). # diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index 1a216d9b3..cc8559fe0 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -102,7 +102,7 @@ server: interface: 0.0.0.0 interface: ::0 access\-control: 10.0.0.0/8 allow - access\-control: 2001:DB8::/64 allow + access\-control: 2001:db8::/64 allow .ft P .fi .UNINDENT @@ -3377,7 +3377,7 @@ zone section below. Configure local data shorthand for a PTR record with the reversed IPv4 or IPv6 address and the host name. For example \fB\(dq192.0.2.4 www.example.com\(dq\fP\&. -TTL can be inserted like this: \fB\(dq2001:DB8::4 7200 www.example.com\(dq\fP +TTL can be inserted like this: \fB\(dq2001:db8::4 7200 www.example.com\(dq\fP .UNINDENT .INDENT 0.0 .TP @@ -4135,6 +4135,9 @@ Default: no If enabled, a query is attempted without this stub section if it fails. The data could not be retrieved and would have caused SERVFAIL because the servers are unreachable, instead it is tried without this stub section. +This can lead to using less specific configured forward/stub/auth zones if +any, or end up to otherwise normal recursive resolution for that particular +query. .sp Default: no .UNINDENT @@ -4255,9 +4258,11 @@ The cert must also match a CA from the .INDENT 0.0 .TP .B forward\-first: \fI\fP -If a forwarded query is met with a SERVFAIL error, and this option is -enabled, Unbound will fall back to normal recursive resolution for this -query as if no query forwarding had been specified. +If a forwarded query is met with a SERVFAIL error and this option is +enabled Unbound will fall back to less specific resolution. +This can lead to using less specific configured forward/stub/auth zones if +any, or end up to otherwise normal recursive resolution for that particular +query. .sp Default: no .UNINDENT @@ -4370,9 +4375,15 @@ does not support AXFR/IXFR for the zone, but if you used \fI\%url\fP to download the zonefile as a text file from a webserver that would work. .sp -If you specify the hostname, you cannot use the domain from the zonefile, -because it may not have that when retrieving that data, instead use a plain -IP address to avoid a circular dependency on retrieving that IP address. +\fBCAUTION:\fP +.INDENT 7.0 +.INDENT 3.5 +If you specify the hostname, you cannot use the domain from the +zonefile, because it may not have that when retrieving that data, +instead use a plain IP address to avoid a circular dependency on +retrieving that IP address. +.UNINDENT +.UNINDENT .UNINDENT .INDENT 0.0 .TP diff --git a/doc/unbound.conf.rst b/doc/unbound.conf.rst index 8f78fb31d..9ec4a9e0b 100644 --- a/doc/unbound.conf.rst +++ b/doc/unbound.conf.rst @@ -102,7 +102,7 @@ all the options. interface: 0.0.0.0 interface: ::0 access-control: 10.0.0.0/8 allow - access-control: 2001:DB8::/64 allow + access-control: 2001:db8::/64 allow .. _unbound.conf.clauses: @@ -1306,6 +1306,9 @@ These options are part of the ``server:`` section. Only interfaces configured with that port number as @number get the QUIC service. The interface uses QUIC for the UDP traffic on that port number. + If the quic-port is set to 0, the server does not init quic code, + and quic is disabled. + This is similar to if quic is not in use, but then explicitly. Default: 853 @@ -2896,7 +2899,7 @@ These options are part of the ``server:`` section. Configure local data shorthand for a PTR record with the reversed IPv4 or IPv6 address and the host name. For example ``"192.0.2.4 www.example.com"``. - TTL can be inserted like this: ``"2001:DB8::4 7200 www.example.com"`` + TTL can be inserted like this: ``"2001:db8::4 7200 www.example.com"`` @@UAHL@unbound.conf@local-zone-tag@@: * <"list of tags">* @@ -3587,6 +3590,9 @@ The :ref:`local-zone: nodefault` (or If enabled, a query is attempted without this stub section if it fails. The data could not be retrieved and would have caused SERVFAIL because the servers are unreachable, instead it is tried without this stub section. + This can lead to using less specific configured forward/stub/auth zones if + any, or end up to otherwise normal recursive resolution for that particular + query. Default: no @@ -3699,9 +3705,11 @@ cache). @@UAHL@unbound.conf.forward@forward-first@@: ** - If a forwarded query is met with a SERVFAIL error, and this option is - enabled, Unbound will fall back to normal recursive resolution for this - query as if no query forwarding had been specified. + If a forwarded query is met with a SERVFAIL error and this option is + enabled Unbound will fall back to less specific resolution. + This can lead to using less specific configured forward/stub/auth zones if + any, or end up to otherwise normal recursive resolution for that particular + query. Default: no diff --git a/edns-subnet/subnetmod.c b/edns-subnet/subnetmod.c index a2a3f1846..5144070a5 100644 --- a/edns-subnet/subnetmod.c +++ b/edns-subnet/subnetmod.c @@ -162,8 +162,15 @@ int ecs_whitelist_check(struct query_info* qinfo, if(!ecs_is_whitelisted(sn_env->whitelist, addr, addrlen, qinfo->qname, qinfo->qname_len, qinfo->qclass)) { - verbose(VERB_ALGO, "subnet store subquery global, name and addr have no subnet treatment."); - qstate->no_cache_store = 0; + /* The stub or forward can have no_cache set.*/ + if(iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL, NULL, 0)) { + verbose(VERB_ALGO, "subnet subquery is not stored globally, stuborfwd is no_cache"); + } else { + verbose(VERB_ALGO, "subnet store subquery global, name and addr have no subnet treatment.%s", + (sq->started_no_cache_store? + " But the subnet module was started with no_cache_store for the super query, and that is still applied to this query":"")); + qstate->no_cache_store = sq->started_no_cache_store; + } } } return 1; @@ -580,6 +587,7 @@ generate_sub_request(struct module_qstate *qstate, int id, struct subnet_qstate* } subsq = (struct subnet_qstate*)subq->minfo[id]; subsq->is_subquery_nonsubnet = 1; + subsq->started_no_cache_store = sq->started_no_cache_store; /* When the client asks 0.0.0.0/0 and the name is not treated * as subnet, it is to be stored in the global cache. diff --git a/iterator/iterator.c b/iterator/iterator.c index 836cb36e0..5013c75ad 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -3603,7 +3603,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, return next_state(iq, INIT_REQUEST_STATE); } else if(type == RESPONSE_TYPE_LAME) { /* Cache the LAMEness. */ - verbose(VERB_DETAIL, "query response was %sLAME", + verbose(VERB_DETAIL, "query response was categorized as %sLAME", dnsseclame?"DNSSEC ":""); if(!dname_subdomain_c(iq->qchase.qname, iq->dp->name)) { log_err("mark lame: mismatch in qname and dpname"); @@ -3642,7 +3642,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, * In this case, the event is just sent directly back to * the QUERYTARGETS_STATE without resetting anything, * because, clearly, the next target must be tried. */ - verbose(VERB_DETAIL, "query response was THROWAWAY"); + verbose(VERB_DETAIL, "query response was categorized as THROWAWAY"); } else { log_warn("A query response came back with an unknown type: %d", (int)type); diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c index e6c7de98d..9971f9e2e 100644 --- a/services/listen_dnsport.c +++ b/services/listen_dnsport.c @@ -1564,7 +1564,7 @@ listen_create(struct comm_base* base, struct listen_port* ports, cp = comm_point_create_udp(base, ports->fd, front->udp_buff, ports->pp2_enabled, cb, cb_arg, ports->socket); - } else if(ports->ftype == listen_type_doq) { + } else if(ports->ftype == listen_type_doq && doq_table) { #ifndef HAVE_NGTCP2 log_warn("Unbound is not compiled with " "ngtcp2. This is required to use DNS " @@ -3274,14 +3274,18 @@ nghttp2_session_callbacks* http2_req_callbacks_create(void) struct doq_table* doq_table_create(struct config_file* cfg, struct ub_randstate* rnd) { - struct doq_table* table = calloc(1, sizeof(*table)); + struct doq_table* table; + + if (!cfg->quic_port) + return NULL; + table = calloc(1, sizeof(*table)); if(!table) return NULL; #ifdef USE_NGTCP2_CRYPTO_OSSL /* Initialize the ossl crypto, it is harmless to call twice, * and this is before use of doq connections. */ if(ngtcp2_crypto_ossl_init() != 0) { - log_err("ngtcp2_crypto_oss_init failed"); + log_err("ngtcp2_crypto_ossl_init failed"); free(table); return NULL; } @@ -3353,7 +3357,7 @@ conn_tree_del(rbnode_type* node, void* arg) { struct doq_table* table = (struct doq_table*)arg; struct doq_conn* conn; - if(!node) + if(!node || !table) return; conn = (struct doq_conn*)node->key; if(conn->timer.timer_in_list) { @@ -3412,6 +3416,7 @@ doq_timer_find_time(struct doq_table* table, struct timeval* tv) { struct doq_timer key; struct rbnode_type* node; + log_assert(table != NULL); memset(&key, 0, sizeof(key)); key.time.tv_sec = tv->tv_sec; key.time.tv_usec = tv->tv_usec; @@ -4921,6 +4926,7 @@ doq_conid_find(struct doq_table* table, const uint8_t* data, size_t datalen) key.node.key = &key; key.cid = (void*)data; key.cidlen = datalen; + log_assert(table != NULL); node = rbtree_search(table->conid_tree, &key); if(node) return (struct doq_conid*)node->key; @@ -5661,6 +5667,8 @@ doq_table_quic_size_available(struct doq_table* table, struct config_file* cfg, size_t mem) { size_t cur; + if (!table) + return 0; lock_basic_lock(&table->size_lock); cur = table->current_size; lock_basic_unlock(&table->size_lock); diff --git a/testcode/doqclient.c b/testcode/doqclient.c index 238a93803..8a34ca31b 100644 --- a/testcode/doqclient.c +++ b/testcode/doqclient.c @@ -2255,7 +2255,7 @@ create_doq_client_data(const char* svr, int port, struct ub_event_base* base, /* Initialize the ossl crypto, it is harmless to call twice, * and this is before use of doq connections. */ if(ngtcp2_crypto_ossl_init() != 0) - fatal_exit("ngtcp2_crypto_oss_init failed"); + fatal_exit("ngtcp2_crypto_ossl_init failed"); #elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_INIT) if(ngtcp2_crypto_quictls_init() != 0) fatal_exit("ngtcp2_crypto_quictls_init failed"); diff --git a/testcode/unitmain.c b/testcode/unitmain.c index 07c016d7b..79ce45f39 100644 --- a/testcode/unitmain.c +++ b/testcode/unitmain.c @@ -283,7 +283,7 @@ net_test(void) unit_assert(strcmp(astr, "1.2.3.0") == 0); unit_assert(ntohs(((struct sockaddr_in*)&a)->sin_port)==53); - res = netblockstrtoaddr("2001:DB8:33:44::/64", 53, + res = netblockstrtoaddr("2001:db8:33:44::/64", 53, &a, &alen, &net); unit_assert(res!=0 && net == 64); addr_to_str(&a, alen, astr, sizeof(astr)); diff --git a/testdata/04-checkconf.tdir/good.all b/testdata/04-checkconf.tdir/good.all index d564f983c..2f80db8a8 100644 --- a/testdata/04-checkconf.tdir/good.all +++ b/testdata/04-checkconf.tdir/good.all @@ -24,7 +24,7 @@ server: # specify every interface on a new 'interface:' labelled line. interface: 192.0.2.153 interface: 192.0.2.154 - interface: 2001:DB8::5 + interface: 2001:db8::5 # port to answer queries from port: 53 diff --git a/testdata/04-checkconf.tdir/good.ifport b/testdata/04-checkconf.tdir/good.ifport index 1aa59d1b7..aba268574 100644 --- a/testdata/04-checkconf.tdir/good.ifport +++ b/testdata/04-checkconf.tdir/good.ifport @@ -11,7 +11,7 @@ server: # specify every interface on a new 'interface:' labelled line. interface: 192.0.2.153 interface: 192.0.2.154 - interface: 2001:DB8::5 + interface: 2001:db8::5 interface: 0.0.0.0@5353 # config diff --git a/testdata/subnet_scopezero_global_nocache.crpl b/testdata/subnet_scopezero_global_nocache.crpl new file mode 100644 index 000000000..3e8fbb25f --- /dev/null +++ b/testdata/subnet_scopezero_global_nocache.crpl @@ -0,0 +1,126 @@ +; config options +server: + target-fetch-policy: "0 0 0 0 0" + module-config: "subnetcache validator iterator" + verbosity: 4 + qname-minimisation: no + ; the domain is not configured for edns-subnet + ;send-client-subnet: 1.2.3.4 + +stub-zone: + name: "." + stub-addr: 193.0.14.129 + +stub-zone: + name: "example.com" + stub-addr: 1.2.3.4 + stub-no-cache: yes +CONFIG_END + +SCENARIO_BEGIN Test subnet cache with scope zero for global cache store. + +; the upstream server. +RANGE_BEGIN 0 100 + ADDRESS 193.0.14.129 + +ENTRY_BEGIN +MATCH opcode qtype qname ednsdata +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +. IN NS +SECTION ANSWER +. IN NS K.ROOT-SERVERS.NET. +SECTION ADDITIONAL +HEX_EDNSDATA_BEGIN + ;; we expect to receive empty +HEX_EDNSDATA_END +K.ROOT-SERVERS.NET. IN A 193.0.14.129 +ENTRY_END +RANGE_END + +RANGE_BEGIN 0 21 + ADDRESS 1.2.3.4 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +SECTION AUTHORITY +SECTION ADDITIONAL +ENTRY_END +RANGE_END + +RANGE_BEGIN 30 50 + ADDRESS 1.2.3.4 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.1 +SECTION AUTHORITY +SECTION ADDITIONAL +ENTRY_END +RANGE_END + +; query for 0.0.0.0/0 +STEP 10 QUERY +ENTRY_BEGIN +HEX_ANSWER_BEGIN + 00 00 01 00 00 01 00 00 ;ID 0 + 00 00 00 01 03 77 77 77 ; www.example.com A? (DO) + 07 65 78 61 6d 70 6c 65 + 03 63 6f 6d 00 00 01 00 + 01 00 00 29 10 00 00 00 + 80 00 00 08 + + 00 08 00 04 ; OPC, optlen + 00 01 00 00 ; ip4, scope 0, source 0 + ;0.0.0.0/0 +HEX_ANSWER_END +ENTRY_END + +STEP 20 CHECK_ANSWER +ENTRY_BEGIN +MATCH all ednsdata +REPLY QR RD RA NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.40 +SECTION AUTHORITY +SECTION ADDITIONAL +HEX_EDNSDATA_BEGIN + 00 08 ; OPC + 00 04 ; option length + 00 01 ; Family + 00 00 ; source mask, scopemask + ; address +HEX_EDNSDATA_END +ENTRY_END + +; It should not be in global cache. +STEP 30 QUERY +ENTRY_BEGIN +REPLY RD NOERROR +SECTION QUESTION +www.example.com. IN A +ENTRY_END + +STEP 40 CHECK_ANSWER +ENTRY_BEGIN +MATCH all ednsdata +REPLY QR RD RA NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. IN A 10.20.30.1 +ENTRY_END + +SCENARIO_END diff --git a/testdata/test_ldnsrr.5 b/testdata/test_ldnsrr.5 index 1f2837a67..c970d9177 100644 --- a/testdata/test_ldnsrr.5 +++ b/testdata/test_ldnsrr.5 @@ -83,7 +83,7 @@ prev-nxt IN A 127.0.0.1 host1.blaat.nl. IN NID 10 0014:4fff:ff20:ee64 host1.blaat.nl. IN L32 10 10.1.2.0 -host1.blaat.nl. IN L64 10 2001:0DB8:1140:1000 +host1.blaat.nl. IN L64 10 2001:db8:1140:1000 host1.blaat.nl. IN LP 10 l64-subnet1.blaat.nl. ;error1 IN NID 1 00fg:4fff:ff20:ee64 diff --git a/util/configparser.y b/util/configparser.y index bf9c196fc..f159b8cec 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -1235,14 +1235,17 @@ server_http_notls_downstream: VAR_HTTP_NOTLS_DOWNSTREAM STRING_ARG server_quic_port: VAR_QUIC_PORT STRING_ARG { OUTYY(("P(server_quic_port:%s)\n", $2)); -#ifndef HAVE_NGTCP2 - log_warn("%s:%d: Unbound is not compiled with " - "ngtcp2. This is required to use DNS " - "over QUIC.", cfg_parser->filename, cfg_parser->line); -#endif - if(atoi($2) == 0) + if(atoi($2) == 0 && strcmp($2,"0")!=0) yyerror("port number expected"); - else cfg_parser->cfg->quic_port = atoi($2); + else { + cfg_parser->cfg->quic_port = atoi($2); +#ifndef HAVE_NGTCP2 + if (cfg_parser->cfg->quic_port != 0) + log_warn("%s:%d: Unbound is not compiled with " + "ngtcp2. This is required to use DNS " + "over QUIC.", cfg_parser->filename, cfg_parser->line); +#endif + } free($2); }; server_quic_size: VAR_QUIC_SIZE STRING_ARG diff --git a/util/data/msgencode.c b/util/data/msgencode.c index 019da7253..8f4639519 100644 --- a/util/data/msgencode.c +++ b/util/data/msgencode.c @@ -1131,22 +1131,30 @@ extended_error_encode(sldns_buffer* buf, uint16_t rcode, sldns_buffer_write_u16(buf, qinfo->qclass); } sldns_buffer_flip(buf); - if(edns) { + if(edns && edns->edns_present) { + uint16_t edns_field_size, ede_size, ede_txt_size; struct edns_data es = *edns; es.edns_version = EDNS_ADVERTISED_VERSION; es.udp_size = EDNS_ADVERTISED_SIZE; es.ext_rcode = (uint8_t)(rcode >> 4); es.bits &= EDNS_DO; - if(sldns_buffer_limit(buf) + calc_edns_field_size(&es) > - edns->udp_size) { + /* EDEs are optional. If space is a concern try in order: + * - removing any EXTRA-TEXT fields from explicit EDEs, or + * - removing all EDEs, + * to see if EDNS can fit. */ + edns_field_size = calc_edns_field_size(&es); + ede_size = calc_ede_option_size(&es, &ede_txt_size); + if(edns->udp_size >= sldns_buffer_limit(buf) + edns_field_size) + attach_edns_record_max_msg_sz(buf, &es, edns->udp_size); + else if(edns->udp_size >= sldns_buffer_limit(buf) + edns_field_size - ede_txt_size) { + ede_trim_text(&es.opt_list_inplace_cb_out); + ede_trim_text(&es.opt_list_out); + attach_edns_record_max_msg_sz(buf, &es, edns->udp_size); + } else if(edns->udp_size >= sldns_buffer_limit(buf) + edns_field_size - ede_size) { edns_opt_list_remove(&es.opt_list_inplace_cb_out, LDNS_EDNS_EDE); edns_opt_list_remove(&es.opt_list_out, LDNS_EDNS_EDE); - if(sldns_buffer_limit(buf) + calc_edns_field_size(&es) > - edns->udp_size) { - return; - } + attach_edns_record_max_msg_sz(buf, &es, edns->udp_size); } - attach_edns_record(buf, &es); } } diff --git a/util/netevent.c b/util/netevent.c index 2943a50d0..01ef54dfe 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -2723,6 +2723,7 @@ doq_server_socket_create(struct doq_table* table, struct ub_randstate* rnd, { size_t doq_buffer_size = 4096; /* bytes buffer size, for one packet. */ struct doq_server_socket* doq_socket; + log_assert(table != NULL); doq_socket = calloc(1, sizeof(*doq_socket)); if(!doq_socket) { return NULL; @@ -2804,6 +2805,7 @@ doq_lookup_repinfo(struct doq_table* table, struct comm_reply* repinfo) { struct doq_conn* conn; struct doq_conn_key key; + log_assert(table != NULL); doq_conn_key_from_repinfo(&key, repinfo); lock_rw_rdlock(&table->lock); conn = doq_conn_find(table, &key.paddr.addr, @@ -5883,6 +5885,7 @@ comm_point_create_doq(struct comm_base *base, int fd, sldns_buffer* buffer, struct comm_point* c = (struct comm_point*)calloc(1, sizeof(struct comm_point)); short evbits; + log_assert(table != NULL); if(!c) return NULL; c->ev = (struct internal_event*)calloc(1,