]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Fix that addrinfo is not kept around but copied and freed, so that
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 15 Mar 2024 12:39:49 +0000 (13:39 +0100)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 15 Mar 2024 12:39:49 +0000 (13:39 +0100)
  log-destaddr uses a copy of the information, much like NSD does.

daemon/daemon.c
daemon/worker.c
doc/Changelog
services/listen_dnsport.c
services/listen_dnsport.h
services/mesh.c
util/netevent.c
util/netevent.h

index 193608d40e0561e40620b6ad39129f467c18a2a1..4870089a7320bca84432f649a66266b59068f6bd 100644 (file)
@@ -321,17 +321,15 @@ static int setup_acl_for_ports(struct acl_list* list,
        struct listen_port* port_list)
 {
        struct acl_addr* acl_node;
-       struct addrinfo* addr;
        for(; port_list; port_list=port_list->next) {
                if(!port_list->socket) {
                        /* This is mainly for testbound where port_list is
                         * empty. */
                        continue;
                }
-               addr = port_list->socket->addr;
                if(!(acl_node = acl_interface_insert(list,
-                       (struct sockaddr_storage*)addr->ai_addr,
-                       (socklen_t)addr->ai_addrlen,
+                       (struct sockaddr_storage*)port_list->socket->addr,
+                       port_list->socket->addrlen,
                        acl_refuse))) {
                        return 0;
                }
index 176abf57d56e939cd42e3d65151759b5f2a49f58..1a0b9abde36e5fcbac77951d65722d7a5f88c09e 100644 (file)
@@ -1454,8 +1454,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
         */
        if(worker->dtenv.log_client_query_messages) {
                log_addr(VERB_ALGO, "request from client", &repinfo->client_addr, repinfo->client_addrlen);
-               log_addr(VERB_ALGO, "to local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
-               dt_msg_send_client_query(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->ssl, c->buffer,
+               log_addr(VERB_ALGO, "to local addr", (void*)repinfo->c->socket->addr, repinfo->c->socket->addrlen);
+               dt_msg_send_client_query(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr, c->type, c->ssl, c->buffer,
                ((worker->env.cfg->sock_queue_timeout && timeval_isset(&c->recv_tv))?&c->recv_tv:NULL));
        }
 #endif
@@ -1944,9 +1944,9 @@ send_reply_rc:
         * sending src (client)/dst (local service) addresses over DNSTAP from send_reply code label (when we serviced local zone for ex.)
         */
        if(worker->dtenv.log_client_response_messages) {
-               log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
+               log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr, repinfo->c->socket->addrlen);
                log_addr(VERB_ALGO, "response to client", &repinfo->client_addr, repinfo->client_addrlen);
-               dt_msg_send_client_response(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->ssl, c->buffer);
+               dt_msg_send_client_response(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr, c->type, c->ssl, c->buffer);
        }
 #endif
        if(worker->env.cfg->log_replies)
@@ -1961,13 +1961,13 @@ send_reply_rc:
                        log_reply_info(NO_VERBOSE, &qinfo,
                                &repinfo->client_addr, repinfo->client_addrlen,
                                tv, 1, c->buffer,
-                               (worker->env.cfg->log_destaddr?(void*)repinfo->c->socket->addr->ai_addr:NULL),
+                               (worker->env.cfg->log_destaddr?(void*)repinfo->c->socket->addr:NULL),
                                c->type);
                } else {
                        log_reply_info(NO_VERBOSE, &qinfo,
                                &repinfo->client_addr, repinfo->client_addrlen,
                                tv, 1, c->buffer,
-                               (worker->env.cfg->log_destaddr?(void*)repinfo->c->socket->addr->ai_addr:NULL),
+                               (worker->env.cfg->log_destaddr?(void*)repinfo->c->socket->addr:NULL),
                                c->type);
                }
        }
index 6d8a1e291cb347cd9209f6de98746738d5a813c9..8359f08f5a1d8321055e832e5c93b9f171c19c41 100644 (file)
@@ -1,3 +1,7 @@
+15 March 2024: Wouter
+       - Fix that addrinfo is not kept around but copied and freed, so that
+         log-destaddr uses a copy of the information, much like NSD does.
+
 13 March 2024: Wouter
        - Fix #1029: rpz trigger clientip and action rpz-passthru not working
          as expected.
index 753550978a0742d92cbb4145c2b71b6c1da8a9bc..26679941b1f7e4536047a6d7e68af72b7e9a821c 100644 (file)
@@ -140,9 +140,11 @@ void
 verbose_print_unbound_socket(struct unbound_socket* ub_sock)
 {
        if(verbosity >= VERB_ALGO) {
+               char buf[256];
                log_info("listing of unbound_socket structure:");
-               verbose_print_addr(ub_sock->addr);
-               log_info("s is: %d, fam is: %s, acl: %s", ub_sock->s,
+               addr_to_str((void*)ub_sock->addr, ub_sock->addrlen, buf,
+                       sizeof(buf));
+               log_info("%s s is: %d, fam is: %s, acl: %s", buf, ub_sock->s,
                        ub_sock->fam == AF_INET?"AF_INET":"AF_INET6",
                        ub_sock->acl?"yes":"no");
        }
@@ -1047,7 +1049,22 @@ make_sock(int stype, const char* ifname, const char* port,
                }
        }
 
-       ub_sock->addr = res;
+       if(!res->ai_addr) {
+               log_err("getaddrinfo returned no address");
+               freeaddrinfo(res);
+               sock_close(s);
+               return -1;
+       }
+       ub_sock->addr = memdup(res->ai_addr, res->ai_addrlen);
+       ub_sock->addrlen = res->ai_addrlen;
+       if(!ub_sock->addr) {
+               log_err("out of memory: allocate listening address");
+               freeaddrinfo(res);
+               sock_close(s);
+               return -1;
+       }
+       freeaddrinfo(res);
+
        ub_sock->s = s;
        ub_sock->fam = hints->ai_family;
        ub_sock->acl = NULL;
@@ -1277,8 +1294,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
                if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
                        &noip6, rcv, snd, reuseport, transparent,
                        tcp_mss, nodelay, freebind, use_systemd, dscp, ub_sock)) == -1) {
-                       if(ub_sock->addr)
-                               freeaddrinfo(ub_sock->addr);
+                       free(ub_sock->addr);
                        free(ub_sock);
                        if(noip6) {
                                log_warn("IPv6 protocol not available");
@@ -1289,8 +1305,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
                /* getting source addr packet info is highly non-portable */
                if(!set_recvpktinfo(s, hints->ai_family)) {
                        sock_close(s);
-                       if(ub_sock->addr)
-                               freeaddrinfo(ub_sock->addr);
+                       free(ub_sock->addr);
                        free(ub_sock);
                        return 0;
                }
@@ -1301,8 +1316,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
                        ?listen_type_udpancil_dnscrypt:listen_type_udpancil,
                        is_pp2, ub_sock)) {
                        sock_close(s);
-                       if(ub_sock->addr)
-                               freeaddrinfo(ub_sock->addr);
+                       free(ub_sock->addr);
                        free(ub_sock);
                        return 0;
                }
@@ -1314,8 +1328,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
                if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1,
                        &noip6, rcv, snd, reuseport, transparent,
                        tcp_mss, nodelay, freebind, use_systemd, dscp, ub_sock)) == -1) {
-                       if(ub_sock->addr)
-                               freeaddrinfo(ub_sock->addr);
+                       free(ub_sock->addr);
                        free(ub_sock);
                        if(noip6) {
                                log_warn("IPv6 protocol not available");
@@ -1332,8 +1345,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
                                listen_type_udpancil:listen_type_udp),
                        is_pp2, ub_sock)) {
                        sock_close(s);
-                       if(ub_sock->addr)
-                               freeaddrinfo(ub_sock->addr);
+                       free(ub_sock->addr);
                        free(ub_sock);
                        return 0;
                }
@@ -1356,8 +1368,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
                if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1,
                        &noip6, 0, 0, reuseport, transparent, tcp_mss, nodelay,
                        freebind, use_systemd, dscp, ub_sock)) == -1) {
-                       if(ub_sock->addr)
-                               freeaddrinfo(ub_sock->addr);
+                       free(ub_sock->addr);
                        free(ub_sock);
                        if(noip6) {
                                /*log_warn("IPv6 protocol not available");*/
@@ -1369,8 +1380,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
                        verbose(VERB_ALGO, "setup TCP for SSL service");
                if(!port_insert(list, s, port_type, is_pp2, ub_sock)) {
                        sock_close(s);
-                       if(ub_sock->addr)
-                               freeaddrinfo(ub_sock->addr);
+                       free(ub_sock->addr);
                        free(ub_sock);
                        return 0;
                }
@@ -1952,8 +1962,7 @@ void listening_ports_free(struct listen_port* list)
                }
                /* rc_ports don't have ub_socket */
                if(list->socket) {
-                       if(list->socket->addr)
-                               freeaddrinfo(list->socket->addr);
+                       free(list->socket->addr);
                        free(list->socket);
                }
                free(list);
index 816d79aea61b04fdee87d65adf22bc80af6bc409..84ac4b068b1bdde971a8cb49119c17703b47b46f 100644 (file)
@@ -107,11 +107,13 @@ enum listen_type {
  * socket properties (just like NSD nsd_socket structure definition)
  */
 struct unbound_socket {
-       /** socket-address structure */
-       struct addrinfo* addr;
+       /** the address of the socket */
+       struct sockaddr* addr;
+       /** length of the address */
+       socklen_t addrlen;
        /** socket descriptor returned by socket() syscall */
        int s;
-       /** address family (AF_INET/IF_INET6) */
+       /** address family (AF_INET/AF_INET6) */
        int fam;
        /** ACL on the socket (listening interface) */
        struct acl_addr* acl;
index 47cfb04249b5cac76b04541123b85a20cd00ade9..3c2b536b45eea05f4e96e2053a913b89b8c2615b 100644 (file)
@@ -1436,7 +1436,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
                log_reply_info(NO_VERBOSE, &m->s.qinfo,
                        &r->query_reply.client_addr,
                        r->query_reply.client_addrlen, duration, 0, r_buffer,
-                       (m->s.env->cfg->log_destaddr?(void*)r->query_reply.c->socket->addr->ai_addr:NULL),
+                       (m->s.env->cfg->log_destaddr?(void*)r->query_reply.c->socket->addr:NULL),
                        r->query_reply.c->type);
        }
 }
index 1fc8c6b8658eabced2ed27283b13779ce2525a7d..980829d087e9a8ff8a46da75b6aec0d231a56b9b 100644 (file)
@@ -4772,9 +4772,9 @@ comm_point_send_reply(struct comm_reply *repinfo)
                 * sending src (client)/dst (local service) addresses over DNSTAP from udp callback
                 */
                if(repinfo->c->dtenv != NULL && repinfo->c->dtenv->log_client_response_messages) {
-                       log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
+                       log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr, repinfo->c->socket->addrlen);
                        log_addr(VERB_ALGO, "response to client", &repinfo->client_addr, repinfo->client_addrlen);
-                       dt_msg_send_client_response(repinfo->c->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type, repinfo->c->ssl, repinfo->c->buffer);
+                       dt_msg_send_client_response(repinfo->c->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr, repinfo->c->type, repinfo->c->ssl, repinfo->c->buffer);
                }
 #endif
        } else {
@@ -4783,9 +4783,9 @@ comm_point_send_reply(struct comm_reply *repinfo)
                 * sending src (client)/dst (local service) addresses over DNSTAP from TCP callback
                 */
                if(repinfo->c->tcp_parent->dtenv != NULL && repinfo->c->tcp_parent->dtenv->log_client_response_messages) {
-                       log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
+                       log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr, repinfo->c->socket->addrlen);
                        log_addr(VERB_ALGO, "response to client", &repinfo->client_addr, repinfo->client_addrlen);
-                       dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type, repinfo->c->ssl,
+                       dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr, repinfo->c->type, repinfo->c->ssl,
                                ( repinfo->c->tcp_req_info? repinfo->c->tcp_req_info->spool_buffer: repinfo->c->buffer ));
                }
 #endif
index dc9619c163b0ae1756874cd45f5545846f497db0..1e4a13f9b7e58d7863205c2731f9b4e97f343402 100644 (file)
@@ -181,6 +181,8 @@ struct comm_point {
        /** if the event is added or not */
        int event_added;
 
+       /** Reference to struct that is part of the listening ports,
+        * where for listening ports information is kept about the address. */
        struct unbound_socket* socket;
 
        /** file descriptor for communication point */