From 52d4d3010991e851b8e9e4d9f923ad1f74d30d69 Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Tue, 23 Feb 2021 12:24:09 +0100 Subject: [PATCH] BUG/MEDIUM: resolvers: Reset server address and port for obselete SRV records 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 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 | 2 ++ src/server.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/resolvers.c b/src/resolvers.c index a10600b06e..a268701c92 100644 --- a/src/resolvers.c +++ b/src/resolvers.c @@ -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); diff --git a/src/server.c b/src/server.c index 2582e92a5d..bb6a57b09b 100644 --- a/src/server.c +++ b/src/server.c @@ -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);