]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Merge branch 'branch-1.25.2'
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 22 Jul 2026 09:33:54 +0000 (11:33 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Wed, 22 Jul 2026 09:33:54 +0000 (11:33 +0200)
32 files changed:
1  2 
configure
configure.ac
daemon/daemon.c
daemon/remote.c
daemon/worker.c
dnscrypt/dnscrypt.c
dnstap/unbound-dnstap-socket.c
doc/unbound.conf.rst
iterator/iterator.c
libunbound/libworker.c
respip/respip.c
services/authzone.c
services/cache/dns.c
services/cache/rrset.c
services/listen_dnsport.c
services/mesh.c
services/mesh.h
services/outside_network.c
services/outside_network.h
smallapp/worker_cb.c
testcode/doqclient.c
testcode/fake_event.c
util/data/msgparse.c
util/data/packed_rrset.c
util/fptr_wlist.c
util/module.h
util/netevent.c
util/netevent.h
validator/val_sigcrypt.c
validator/val_utils.c
validator/val_utils.h
validator/validator.c

diff --cc configure
Simple merge
diff --cc configure.ac
Simple merge
diff --cc daemon/daemon.c
Simple merge
diff --cc daemon/remote.c
Simple merge
diff --cc daemon/worker.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc respip/respip.c
Simple merge
index 430674b0cb75259b8b02885d2b9f1c2cb6070f40,e7a55391650d7945ee5cb3dc88d12d9841ed4315..4218b8e82466149ac72a770ffb7ac4a0607092d9
@@@ -5853,35 -5743,9 +5853,34 @@@ xfr_master_add_addrs(struct auth_master
        }
  }
  
 +/** check if the lookup target name equals the found answer name. */
 +static int
 +xfer_target_equals_answer_name(struct auth_master* lookup_target,
 +      struct ub_packed_rrset_key* answer, struct query_info* rq,
 +      struct reply_info* rep)
 +{
 +      uint8_t qname[LDNS_MAX_DOMAINLEN+1];
 +      size_t qname_len;
 +      if(!lookup_target) return 0;
 +      if(!answer) return 0;
 +      qname_len = sizeof(qname);
 +      if(sldns_str2wire_dname_buf(lookup_target->host, qname, &qname_len)
 +              != 0) {
 +              verbose(VERB_ALGO, "xfer_target_equals_answer_name: could not parse auth host name");
 +              return 0;
 +      }
 +      if(query_dname_compare(answer->rk.dname, qname) == 0)
 +              return 1;
 +      /* It could be a CNAME. */
 +      if(reply_find_rrset_section_an(rep, qname, qname_len,
 +              LDNS_RR_TYPE_CNAME, rq->qclass))
 +              return 1;
 +      return 0;
 +}
 +
  /** callback for task_transfer lookup of host name, of A or AAAA */
  void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
-       enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus),
-       int ATTR_UNUSED(was_ratelimited))
+       enum sec_status sec, char* why_bogus, int ATTR_UNUSED(was_ratelimited))
  {
        struct auth_xfer* xfr = (struct auth_xfer*)arg;
        struct module_env* env;
Simple merge
index 6fd9bc6e732b0b8d6835c409805d891ee3d53b1f,79bf473bb53d470b8366775ecf6030b501c1f0c1..9b0319140b7b213b7e741666de8c05809077b2ee
@@@ -268,8 -291,14 +298,16 @@@ void rrset_cache_update_wildcard(struc
  {
        struct rrset_ref ref;
        uint8_t wc_dname[LDNS_MAX_DOMAINLEN+3];
 +      uint8_t* new_dname;
 +      size_t new_dname_len;
+       /* See if the RRSIG signer name allows this wildcard,
+        * the new rrset should fall within the zone of the RRSIG signer(s). */
+       if(!dname_subdomain_rrsig_signers(ce, rrset)) {
+               verbose(VERB_ALGO, "wildcard canonical parent outside signer authority");
+               return;
+       }
        rrset = packed_rrset_copy_alloc(rrset, alloc, timenow);
        if(!rrset) {
                log_err("malloc failure in rrset_cache_update_wildcard");
index 58b74863ff31bd4de2af878010f982c87c0c3613,38b493a256dbe10c5263c73aa09c91c93e8a3980..8ef084e5e299996dbad8d7fba6b903a66dc476cf
@@@ -2168,7 -2167,7 +2167,7 @@@ void tcp_req_info_clear(struct tcp_req_
        while(open) {
                nopen = open->next;
                mesh_state_remove_reply(open->mesh, open->mesh_state, req->cp,
--                      NULL);
++                      NULL, NULL);
                free(open);
                open = nopen;
        }
@@@ -3607,6 -3615,11 +3615,11 @@@ stream_tree_del(rbnode_type* node, void
        if(!node)
                return;
        stream = (struct doq_stream*)node;
 -                      args->conn->doq_socket->cp, stream);
+       if(stream->mesh_state) {
+               mesh_state_remove_reply(stream->mesh, stream->mesh_state,
++                      args->conn->doq_socket->cp, NULL, stream);
+               stream->mesh_state = NULL;
+       }
        if(stream->in)
                doq_table_quic_size_subtract(table, stream->inlen);
        if(stream->out)
@@@ -3626,10 -3639,13 +3639,14 @@@ doq_conn_delete(struct doq_conn* conn, 
        lock_rw_unlock(&conn->table->conid_lock);
        /* Remove the app data from ngtcp2 before SSL_free of conn->ssl,
         * because the ngtcp2 conn is deleted. */
 -      SSL_set_app_data(conn->ssl, NULL);
 +      if(conn->ssl)
 +              SSL_set_app_data(conn->ssl, NULL);
        if(conn->stream_tree.count != 0) {
-               traverse_postorder(&conn->stream_tree, stream_tree_del, table);
+               struct doq_stream_tree_del_args args;
+               memset(&args, 0, sizeof(args));
+               args.table = table;
+               args.conn = conn;
+               traverse_postorder(&conn->stream_tree, stream_tree_del, &args);
        }
        free(conn->key.dcid);
        SSL_free(conn->ssl);
@@@ -3942,6 -3954,11 +3955,11 @@@ doq_stream_close(struct doq_conn* conn
        if(stream->is_closed)
                return 1;
        stream->is_closed = 1;
 -                      conn->doq_socket->cp, stream);
+       if(stream->mesh_state) {
+               mesh_state_remove_reply(stream->mesh, stream->mesh_state,
++                      conn->doq_socket->cp, NULL, stream);
+               stream->mesh_state = NULL;
+       }
        doq_stream_off_write_list(conn, stream);
        if(send_shutdown) {
                verbose(VERB_ALGO, "doq: shutdown stream_id %d with app_error_code %d",
diff --cc services/mesh.c
index edfac6cf4d37e0d1972f336521066358085aaf14,99361b17f9641232e9013dde50d5845e91626330..d664e4797759bd2f9948b73551e03fb7e6c46833
@@@ -590,9 -554,10 +594,11 @@@ void mesh_new_client(struct mesh_area* 
                        goto servfail_mem;
                }
        }
 +      added_tcp = 1;
        if(rep->c->use_h2) {
                http2_stream_add_meshstate(rep->c->h2_stream, mesh, s);
+       } else if(rep->c->type == comm_doq && rep->doq_stream) {
+               doq_stream_add_meshstate(rep->doq_stream, mesh, s);
        }
        /* add serve expired timer if required and not already there */
        if(timeout && !mesh_serve_expired_init(s, timeout)) {
@@@ -648,12 -611,9 +654,14 @@@ servfail_mem
                qinfo, qid, qflags, edns);
        if(rep->c->use_h2)
                http2_stream_remove_mesh_state(rep->c->h2_stream);
+       else if(rep->c->type == comm_doq && rep->doq_stream)
+               doq_stream_remove_mesh_state(rep->doq_stream);
        comm_point_send_reply(rep);
 +      if(added_reply_without_accounting) {
 +              mesh_remove_reply_without_accounting(s, repadded);
 +              if(added_tcp && rep->c->tcp_req_info)
 +                      tcp_req_info_remove_mesh_state(rep->c->tcp_req_info, s);
 +      }
        if(added)
                mesh_state_delete(&s->s);
        return;
@@@ -2437,7 -2388,7 +2459,8 @@@ void mesh_list_remove(struct mesh_state
  }
  
  void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
-       struct comm_point* cp, struct http2_stream* h2_stream)
 -      struct comm_point* cp, struct doq_stream* doq_stream)
++      struct comm_point* cp, struct http2_stream* h2_stream,
++      struct doq_stream* doq_stream)
  {
        struct mesh_reply* n, *prev = NULL;
        n = m->reply_list;
        if(!n) return; /* nothing to remove, also no accounting needed */
        while(n) {
                if(n->query_reply.c == cp
-                       && (!h2_stream || n->h2_stream == h2_stream)) {
 -                      && (!doq_stream || n->query_reply.doq_stream == doq_stream)) {
++                      && (!h2_stream || n->h2_stream == h2_stream)
++                      && (!doq_stream || n->query_reply.doq_stream == doq_stre
++am)) {
                        /* unlink it */
                        if(prev) prev->next = n->next;
                        else m->reply_list = n->next;
diff --cc services/mesh.h
index 77b3c7025680db631681a1801b81ae8a34d985f0,6ea63d098916f9f57f8ac7641fcc262e5dd406c9..0f1d91c0020a0b8464118732afbec1c5237eb02b
@@@ -705,11 -683,11 +705,14 @@@ void mesh_list_remove(struct mesh_state
   * @param mesh: to update the counters.
   * @param m: the mesh state.
   * @param cp: the comm_point to remove from the list.
 + * @param h2_stream: if not NULL, it specifies the h2_stream to match
 + *    for the delete.
+  * @param doq_stream: if not NULL, it specifies the doq_stream to match
+  *    for the delete.
   */
  void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
-       struct comm_point* cp, struct http2_stream* h2_stream);
 -      struct comm_point* cp, struct doq_stream* doq_stream);
++      struct comm_point* cp, struct http2_stream* h2_stream,
++      struct doq_stream* doq_stream);
  
  /** Callback for when the serve expired client timer has run out.  Tries to
   * find an expired answer in the cache and reply that to the client.
@@@ -756,9 -734,12 +759,13 @@@ void mesh_respond_serve_expired(struct 
   * @param qflags: flags from client query.
   * @param cb: callback function.
   * @param cb_arg: callback user arg.
 + * @param unique_info: if not NULL, used to find a unique state for removal.
   */
  void mesh_remove_callback(struct mesh_area* mesh, struct query_info* qinfo,
 -      uint16_t qflags, mesh_cb_func_type cb, void* cb_arg);
 +      uint16_t qflags, mesh_cb_func_type cb, void* cb_arg, void* unique_info);
  
+ /** Copy the client info to the query region. */
+ struct respip_client_info* mesh_copy_client_info(struct regional* region,
+       struct respip_client_info* cinfo);
  #endif /* SERVICES_MESH_H */
index 4d29165d371ca25f7562f670aad6039ee615b29c,9dfa8b4d0c4634885410158c0aac97ebe09135bb..50028fc1ed659cd88aada31f95efff3775125526
@@@ -1707,11 -1702,11 +1702,17 @@@ static int setup_if(struct port_if* pif
           !netblockstrtoaddr(addrstr, UNBOUND_DNS_PORT,
                              &pif->addr, &pif->addrlen, &pif->pfxlen))
                return 0;
 +#ifdef INT_MAX
 +      if(numfd > (size_t)INT_MAX) {
 +              log_err("num_ports exceeds INT_MAX");
 +              return 0;
 +      }
++#endif
+ #ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
+       pif->shpif = shared_ports_find_if(shp, &pif->addr, pif->addrlen,
+               pif->pfxlen);
+ #else
+       (void)shp;
  #endif
        pif->maxout = (int)numfd;
        pif->inuse = 0;
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc util/module.h
Simple merge
diff --cc util/netevent.c
index 37b29bc243828d33eec2bcce485edad761987cd2,b7092b88a876d02ddb06f07710d00b3dee8b0183..432fead1b19dfe2232a935d510b1076ef4724df6
@@@ -3241,7 -3166,7 +3233,7 @@@ static void http2_stream_delete(struct 
  {
        if(h2_stream->mesh_state) {
                mesh_state_remove_reply(h2_stream->mesh, h2_stream->mesh_state,
-                       h2_session->c, h2_stream);
 -                      h2_session->c, NULL);
++                      h2_session->c, h2_stream, NULL);
                h2_stream->mesh_state = NULL;
        }
        http2_req_stream_clear(h2_stream);
diff --cc util/netevent.h
Simple merge
index 674db9d4051d6f762f9e2e0625b99c891b2227c2,16c01d2ee37256d76cc0e2d45441cd0ab3402f34..8cfbb146611f86d208ee6d8fe5dff9d4e86df62a
@@@ -1106,7 -1094,7 +1106,8 @@@ canonicalize_rdata(sldns_buffer* buf, s
        size_t len)
  {
        uint8_t* datstart = sldns_buffer_current(buf)-len+2;
 +      uint8_t* datend = sldns_buffer_current(buf);
+       size_t firstlen;
        switch(ntohs(rrset->rk.type)) {
                case LDNS_RR_TYPE_NXT: 
                case LDNS_RR_TYPE_NS:
                case LDNS_RR_TYPE_RP:
                case LDNS_RR_TYPE_SOA:
                        /* two names after another */
 -                      query_dname_tolower(datstart);
 +                      canon_dname_tolower(datstart, datend);
-                       canon_dname_tolower(datstart +
-                               dname_valid(datstart, len-2), datend);
+                       firstlen = dname_valid(datstart, len-2);
+                       if(firstlen && firstlen < len-2)
 -                              query_dname_tolower(datstart + firstlen);
++                              canon_dname_tolower(datstart + firstlen, datend);
                        return;
                case LDNS_RR_TYPE_RT:
                case LDNS_RR_TYPE_AFSDB:
                        if(len < 2+2+1) 
                                return;
                        datstart += 2;
 -                      query_dname_tolower(datstart);
 +                      canon_dname_tolower(datstart, datend);
-                       canon_dname_tolower(datstart +
-                               dname_valid(datstart, len-2-2), datend);
+                       firstlen = dname_valid(datstart, len-2-2);
+                       if(firstlen && firstlen < len-2-2)
 -                              query_dname_tolower(datstart + firstlen);
++                              canon_dname_tolower(datstart + firstlen, datend);
                        return;
                case LDNS_RR_TYPE_NAPTR:
                        if(len < 2+4)
Simple merge
Simple merge
Simple merge