]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist-resolver: Fix a bug when we get new IPs for a server 15737/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 27 Jun 2025 14:09:18 +0000 (16:09 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 27 Jun 2025 14:13:32 +0000 (16:13 +0200)
The `dnsdist-resolver` script regularly checks the IPs corresponding
to a backend `hostname`, and updates our backend accordingly:
- if an IP we previously received vanishes, it removes the backend
  corresponding to that IP
- if a new IP shows up, it adds a new backend

The existing code tries to avoid some work by keeping track of the
number of IPs associated to a given server, skipping the comparisons
of recently received IPs to existing ones if the number did not change.
This unfortunately does not work well if we get the same number of IPs
but with different IPs in the set.
This caused some backends to never get removed and stay along as ghosts,
as well as some new IPs to never be picked up.

Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
dockerdata/dnsdist-resolver.lua

index 16c82fc9d408da921464fab71b6787b45891c484..be8edd3ebf9c94b7850fee20f01e23982d00bccc 100644 (file)
@@ -15,7 +15,6 @@ _M.verbose = false
 -- key = name
 -- value = {address, serverObject} (should make these named members)
 local ourservers = {}
-local ourcount = {}
 
 -- Global variable for store results for getAddressInfo() function
 local resout = {}
@@ -109,39 +108,21 @@ function _M.maintenance()
             end
         end
 
-        -- init our current count
-        if ourcount[name] == nil then
-            ourcount[name] = #ips
-        end
-
-        -- increase our current count if necessary
-        if #ips > ourcount[name] then
-            ourcount[name] = #ips
-            if _M.verbose then
-                infolog("increasing count to " .. ourcount[name] .. " for " .. name)
-            end
-        end
-
-        -- remove servers when we've lost ips
-        if #ips < ourcount[name] then
-            for ourserver, server in pairs(ourservers) do
-                -- check if we match the prefix and the ip is gone
-                if ourserver:find(name, 1, true) == 1 and has_value(ips, server[1]) == false then
-                    ourcount[name] = #ips
-                    if _M.verbose then
-                        infolog("ip address not found anymore " .. server[1])
-                        infolog("decreasing count to " .. ourcount[name])
-                    end
-                    removeServer(ourserver)
+        -- remove servers if they are no longer present
+        for ourserver, server in pairs(ourservers) do
+            -- check if we match the prefix and the ip is gone
+            if ourserver:find(name, 1, true) == 1 and has_value(ips, server[1]) == false then
+                if _M.verbose then
+                    infolog("ip address not found anymore " .. server[1])
                 end
+                removeServer(ourserver)
             end
-        else
-            for _, ip in ipairs(ips) do
-                -- it has IPs
-                if _M.servers[name] ~= nil then
-                    -- we want this server
-                    setServer(name, ip)
-                end
+        end
+        for _, ip in ipairs(ips) do
+            -- it has IPs
+            if _M.servers[name] ~= nil then
+                -- we want this server
+                setServer(name, ip)
             end
         end
     end