]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: resolvers: Reset server address and port for obselete SRV records
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 23 Feb 2021 11:24:09 +0000 (12:24 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 24 Feb 2021 20:58:45 +0000 (21:58 +0100)
When a SRV record expires, the ip/port assigned to the associated server are
now removed. Otherwise, the server is stopped but keeps its ip/port while
the server hostname is removed. It is confusing when the servers state are
retrieve on the CLI and may be a problem if saved in a server-state
file. Because the reload may fail because of this inconsistency.

Here is an example:

 * Declare a server template in a backend, using the resolver <dns>

server-template test 2 _http._tcp.example.com resolvers dns check

 * 2 SRV records are announced with the corresponding additional
   records. Thus, 2 servers are filled. Here is the "show servers state"
   output :

2 frt 1 test1 192.168.1.1 2 64 0 1 2 15 3 4 6 0 0 0 http1.example.com 8001 _http._tcp.example.com 0 0 - - 0
2 frt 2 test2 192.168.1.2 2 64 0 1 1 15 3 4 6 0 0 0 http2.example.com 8002 _http._tcp.example.com 0 0 - - 0

 * Then, one additional record is removed (or a SRV record is removed, the
   result is the same). Here is the new "show servers state" output :

2 frt 1 test1 192.168.1.1 2 64 0 1 38 15 3 4 6 0 0 0 http1.example.com 8001 _http._tcp.example.com 0 0 - - 0
2 frt 2 test2 192.168.1.2 0 96 0 1 19 15 3 0 14 0 0 0 - 8002 _http._tcp.example.com 0 0 - - 0

On reload, if a server-state file is used, this leads to undefined behaviors
depending on the configuration.

This patch should be backported as far as 2.0.

src/resolvers.c
src/server.c

index a10600b06ec62151194a769f7c236d858d4c9ff2..a268701c92d966ea4cfaa6fd82584c998e529726 100644 (file)
@@ -577,6 +577,8 @@ static void resolv_check_response(struct resolv_resolution *res)
                                                srv->hostname        = NULL;
                                                srv->hostname_dn     = NULL;
                                                srv->hostname_dn_len = 0;
+                                               memset(&srv->addr, 0, sizeof(srv->addr));
+                                               srv->svc_port = 0;
                                                resolv_unlink_resolution(srv->resolv_requester);
                                        }
                                        HA_SPIN_UNLOCK(SERVER_LOCK, &srv->lock);
index 2582e92a5d89bf0ad46df7a033ef62df723fe985..bb6a57b09bb3c92cacf15cfe9192443815e6e517 100644 (file)
@@ -4135,6 +4135,8 @@ int srvrq_resolution_error_cb(struct resolv_requester *requester, int error_code
                        s->hostname        = NULL;
                        s->hostname_dn     = NULL;
                        s->hostname_dn_len = 0;
+                       memset(&s->addr, 0, sizeof(s->addr));
+                       s->svc_port = 0;
                        resolv_unlink_resolution(s->resolv_requester);
                }
                HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);