Several resolver configuration error paths open-code nameserver
transport cleanup. They also assume that a nameserver owns either a
datagram transport or a stream transport, but never both.

Add dns_nameserver_deinit() and use it from these error paths. The
helper releases each transport's configuration-time allocations
independently and clears its pointer. No functional change is intended.
---
 include/haproxy/dns.h |  1 +
 src/dns.c             | 19 +++++++++++++++++++
 src/resolvers.c       | 28 ++++------------------------
 3 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/include/haproxy/dns.h b/include/haproxy/dns.h
index 84181c43d..3e0cd5939 100644
--- a/include/haproxy/dns.h
+++ b/include/haproxy/dns.h
@@ -29,5 +29,6 @@ int dns_send_nameserver(struct dns_nameserver *ns, void *buf, 
size_t len);
 ssize_t dns_recv_nameserver(struct dns_nameserver *ns, void *data, size_t 
size);
 int dns_dgram_init(struct dns_nameserver *ns, struct sockaddr_storage *sk);
 int dns_stream_init(struct dns_nameserver *ns, struct server *s);
+void dns_nameserver_deinit(struct dns_nameserver *ns);
 
 #endif // _HAPROXY_DNS_H
diff --git a/src/dns.c b/src/dns.c
index 50f6e8ae0..53e71de0e 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -1417,6 +1417,25 @@ int dns_stream_init(struct dns_nameserver *ns, struct 
server *srv)
        return -1;
 }
 
+/* Releases transport allocations owned by <ns>. */
+void dns_nameserver_deinit(struct dns_nameserver *ns)
+{
+       if (ns->dgram) {
+               dns_ring_free(ns->dgram->ring_req);
+               free(ns->dgram);
+               ns->dgram = NULL;
+       }
+
+       if (ns->stream) {
+               dns_ring_free(ns->stream->ring_req);
+               task_destroy(ns->stream->task_req);
+               task_destroy(ns->stream->task_rsp);
+               task_destroy(ns->stream->task_idle);
+               free(ns->stream);
+               ns->stream = NULL;
+       }
+}
+
 int init_dns_buffers()
 {
        dns_msg_trash = malloc(DNS_TCP_MSG_MAX_SIZE);
diff --git a/src/resolvers.c b/src/resolvers.c
index 65612ab92..06fb19c41 100644
--- a/src/resolvers.c
+++ b/src/resolvers.c
@@ -3590,8 +3590,7 @@ static int parse_resolve_conf(char **errmsg, char 
**warnmsg)
                        if (errmsg)
                                memprintf(errmsg, "parsing 
[/etc/resolv.conf:%d] : out of memory.", resolv_linenum);
                        err_code |= ERR_ALERT | ERR_FATAL;
-                       dns_ring_free(newnameserver->dgram->ring_req);
-                       free(newnameserver->dgram);
+                       dns_nameserver_deinit(newnameserver);
                        free(newnameserver);
                        goto resolv_out;
                }
@@ -3602,8 +3601,7 @@ static int parse_resolve_conf(char **errmsg, char 
**warnmsg)
                                memprintf(errmsg, "parsing 
[/etc/resolv.conf:%d] : out of memory.", resolv_linenum);
                        err_code |= ERR_ALERT | ERR_FATAL;
                        free((char *)newnameserver->conf.file);
-                       dns_ring_free(newnameserver->dgram->ring_req);
-                       free(newnameserver->dgram);
+                       dns_nameserver_deinit(newnameserver);
                        free(newnameserver);
                        goto resolv_out;
                }
@@ -3822,16 +3820,7 @@ int cfg_parse_resolvers(const char *file, int linenum, 
char **args, int kwm)
                if ((newnameserver->conf.file = strdup(file)) == NULL) {
                        ha_alert("parsing [%s:%d] : out of memory.\n", file, 
linenum);
                        err_code |= ERR_ALERT | ERR_ABORT;
-                       if (newnameserver->stream) {
-                               dns_ring_free(newnameserver->stream->ring_req);
-                               task_destroy(newnameserver->stream->task_req);
-                               task_destroy(newnameserver->stream->task_rsp);
-                               task_destroy(newnameserver->stream->task_idle);
-                               free(newnameserver->stream);
-                       } else if (newnameserver->dgram) {
-                               dns_ring_free(newnameserver->dgram->ring_req);
-                               free(newnameserver->dgram);
-                       }
+                       dns_nameserver_deinit(newnameserver);
                        free(newnameserver);
                        goto out;
                }
@@ -3840,16 +3829,7 @@ int cfg_parse_resolvers(const char *file, int linenum, 
char **args, int kwm)
                        ha_alert("parsing [%s:%d] : out of memory.\n", file, 
linenum);
                        err_code |= ERR_ALERT | ERR_ABORT;
                        free((char *)newnameserver->conf.file);
-                       if (newnameserver->stream) {
-                               dns_ring_free(newnameserver->stream->ring_req);
-                               task_destroy(newnameserver->stream->task_req);
-                               task_destroy(newnameserver->stream->task_rsp);
-                               task_destroy(newnameserver->stream->task_idle);
-                               free(newnameserver->stream);
-                       } else if (newnameserver->dgram) {
-                               dns_ring_free(newnameserver->dgram->ring_req);
-                               free(newnameserver->dgram);
-                       }
+                       dns_nameserver_deinit(newnameserver);
                        free(newnameserver);
                        goto out;
                }
-- 
2.54.0

Reply via email to