]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: resolvers: add support of tcp address on nameserver line.
authorEmeric Brun <ebrun@haproxy.com>
Wed, 7 Apr 2021 14:04:54 +0000 (16:04 +0200)
committerWilly Tarreau <w@1wt.eu>
Thu, 8 Apr 2021 12:20:40 +0000 (14:20 +0200)
This patch re-works configuration parsing, it removes the "server"
lines from "resolvers" sections introduced in commit 56fc5d9eb:
MEDIUM: resolvers: add supports of TCP nameservers in resolvers.

It also extends the nameserver lines to support stream server
addresses such as:

resolvers
  nameserver localhost tcp@127.0.0.1:53

Doing so, a part of nameserver's init code was factorized in
function 'parse_resolvers' and removed from 'post_parse_resolvers'.

doc/configuration.txt
src/resolvers.c

index 128f66fcabcbf7d69c4817c8d5666669b7f4d6ef..01a01ecccd581e0323c5acc851f19f30b95f625b 100644 (file)
@@ -14828,18 +14828,16 @@ accepted_payload_size <nb>
         nameservers to handle huge DNS responses, you should put this value
         to the max: 65535.
 
-nameserver <id> <ip>:<port>
-  UDP DNS server description:
-    <id>   : label of the server, should be unique
-    <ip>   : IP address of the server
-    <port> : port where the DNS service actually runs
-
-server <name> <address> [param*]
-  Used to configure a DNS TCP or stream server. This supports for all
-  "server" parameters found in 5.2 paragraph. Some of these parameters
-  are irrelevant for DNS resolving. Note: currently 4 queries are pipelined
-  on the same connections. A batch of idle connections are removed every
-  5 seconds. "maxconn" can be configured to limit the amount of those
+nameserver <name> <address>[:port] [param*]
+  Used to configure a nameserver. <name> of the nameserver should ne unique.
+  By default the <address> is considered of type datagram. This means if an
+  IPv4 or IPv6 is configured without special address prefixes (paragraph 11.)
+  the UDP protocol will be used.  If an stream protocol address prefix is used,
+  the nameserver will be considered as a stream server (TCP for instance) and
+  "server" parameters found in 5.2 paragraph which are relevant for DNS
+  resolving will be considered.  Note: currently, in TCP mode, 4 queries are
+  pipelined on the same connections. A batch of idle connections are removed
+  every 5 seconds. "maxconn" can be configured to limit the amount of those
   concurrent connections and TLS should also usable if the server supports.
 
 parse-resolv-conf
@@ -14885,6 +14883,7 @@ timeout <event> <time>
    resolvers mydns
      nameserver dns1 10.0.0.1:53
      nameserver dns2 10.0.0.2:53
+     nameserver dns3 tcp@10.0.0.3:53
      parse-resolv-conf
      resolve_retries       3
      timeout resolve       1s
index 4ad2e683374e9b6881e492db204f9193840b06ce..1ba5d660413ae9d2c0083531e0d8959e5d805d85 100644 (file)
@@ -2968,14 +2968,11 @@ int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
                LIST_INIT(&curr_resolvers->resolutions.wait);
                HA_SPIN_INIT(&curr_resolvers->lock);
        }
-       else if (strcmp(args[0],"server") == 0) {
-               err_code |= parse_server(file, linenum, args, curr_resolvers->px, NULL,
-                                        SRV_PARSE_PARSE_ADDR|SRV_PARSE_INITIAL_RESOLVE);
-        }
        else if (strcmp(args[0], "nameserver") == 0) { /* nameserver definition */
                struct dns_nameserver *newnameserver = NULL;
                struct sockaddr_storage *sk;
                int port1, port2;
+               struct protocol *proto;
 
                if (!*args[2]) {
                        ha_alert("parsing [%s:%d] : '%s' expects <name> and <addr>[:<port>] as arguments.\n",
@@ -3001,8 +2998,8 @@ int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
                        }
                }
 
-               sk = str2sa_range(args[2], NULL, &port1, &port2, NULL, NULL,
-                                 &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_DGRAM);
+               sk = str2sa_range(args[2], NULL, &port1, &port2, NULL, &proto,
+                                 &errmsg, NULL, NULL, PA_O_RESOLVE | PA_O_PORT_OK | PA_O_PORT_MAND | PA_O_DGRAM | PA_O_STREAM | PA_O_DEFAULT_DGRAM);
                if (!sk) {
                        ha_alert("parsing [%s:%d] : '%s %s' : %s\n", file, linenum, args[0], args[1], errmsg);
                        err_code |= ERR_ALERT | ERR_FATAL;
@@ -3015,7 +3012,21 @@ int cfg_parse_resolvers(const char *file, int linenum, char **args, int kwm)
                        goto out;
                }
 
-               if (dns_dgram_init(newnameserver, sk) < 0) {
+               if (proto && proto->ctrl_type == SOCK_STREAM) {
+                       err_code |= parse_server(file, linenum, args, curr_resolvers->px, NULL,
+                                                SRV_PARSE_PARSE_ADDR|SRV_PARSE_INITIAL_RESOLVE);
+                       if (err_code & (ERR_FATAL|ERR_ABORT)) {
+                               err_code |= ERR_ABORT;
+                               goto out;
+                       }
+
+                       if (dns_stream_init(newnameserver, curr_resolvers->px->srv) < 0) {
+                               ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
+                               err_code |= ERR_ALERT|ERR_ABORT;
+                               goto out;
+                       }
+               }
+               else if (dns_dgram_init(newnameserver, sk) < 0) {
                        ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
                        err_code |= ERR_ALERT | ERR_ABORT;
                        goto out;
@@ -3316,18 +3327,6 @@ int cfg_post_parse_resolvers()
                if (curr_resolvers->px) {
                        srv = curr_resolvers->px->srv;
                        while (srv) {
-                               struct dns_nameserver *ns;
-
-                               list_for_each_entry(ns, &curr_resolvers->nameservers, list) {
-                                       /* Error if two resolvers owns the same name */
-                                       if (strcmp(ns->id, srv->id) == 0) {
-                                               ha_alert("Parsing [%s:%d]: nameserver '%s' has same name as another nameserver (declared at %s:%d).\n",
-                                                        srv->conf.file, srv->conf.line, srv->id, ns->conf.file, ns->conf.line);
-                                               err_code |= ERR_ALERT | ERR_FATAL;
-                                               break;
-                                       }
-                               }
-
                                /* init ssl if needed */
                                if (srv->use_ssl == 1 && xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->prepare_srv) {
                                        if (xprt_get(XPRT_SSL)->prepare_srv(srv)) {
@@ -3336,37 +3335,6 @@ int cfg_post_parse_resolvers()
                                                break;
                                        }
                                }
-
-                               /* allocate nameserver */
-                               ns = calloc(1, sizeof(*ns));
-                               if (!ns) {
-                                       ha_alert("memory allocation error initializing tcp server '%s' in resolvers section '%s'.\n", srv->id, curr_resolvers->id);
-                                       err_code |= ERR_ALERT | ERR_FATAL;
-                                       break;
-                               }
-
-                               if (dns_stream_init(ns, srv) < 0) {
-                                       ha_alert("memory allocation error initializing tcp server '%s' in resolvers section '%s'.\n", srv->id, curr_resolvers->id);
-                                       err_code |= ERR_ALERT|ERR_ABORT;
-                                       break;
-                               }
-
-                               ns->conf.file = strdup(srv->conf.file);
-                               if (!ns->conf.file) {
-                                       ha_alert("memory allocation error initializing tcp server '%s' in resolvers section '%s'.\n", srv->id, curr_resolvers->id);
-                                       err_code |= ERR_ALERT|ERR_ABORT;
-                                       break;
-                               }
-                               ns->id = strdup(srv->id);
-                               if (!ns->id) {
-                                       ha_alert("memory allocation error initializing tcp server '%s' in resolvers section '%s'.\n", srv->id, curr_resolvers->id);
-                                       err_code |= ERR_ALERT|ERR_ABORT;
-                                       break;
-                               }
-                               ns->conf.line = srv->conf.line;
-                               ns->process_responses = resolv_process_responses;
-                               ns->parent = curr_resolvers;
-                               LIST_ADDQ(&curr_resolvers->nameservers, &ns->list);
                                srv = srv->next;
                        }
                }