BUG/MEDIUM: server/dns: prevent DOWN/UP flap upon resolution timeout or error

This is a complementary patch to c16eba818 ("BUG/MEDIUM: server/dns:
preserve server's port upon resolution timeout or error").

Indeed, since c16eba818, the port is properly preserved, but unsetting
server's address this way results in server_atomic_sync() function
thinking that we're actually setting a new address and not unsetting
the previous one because addr family is != AF_UNSPEC.

Upon DNS timeout, this could be observed:

[WARNING]  (2588257) : Server http/s1 is going DOWN for maintenance (DNS timeout status). 0 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
[WARNING]  (2588257) : Server http/s1 ('test1.localhost') is UP/READY (resolves again).

Notice that server timeouts and then immediately resolves again. Of course
in this case case the server's address was properly set to 0, meaning
that the server will not receive any traffic, but it is confusing and
could result in haproxy temporarily thinking that the server is actually
available while it's not.

To properly fix the issue and restore historical behavior, let's
explicitly set inetaddr's family to AF_UNSPEC after fetching original
server's address.

It should be backported in 3.0 with c16eba818.
This commit is contained in:
Aurelien DARRAGON 2024-06-28 09:41:56 +02:00
parent 290659ffd3
commit 80aba1d284

View File

@ -4595,6 +4595,7 @@ int snr_resolution_cb(struct resolv_requester *requester, struct dns_counters *c
/* unset server's addr, keep port */
server_get_inetaddr(s, &srv_addr);
srv_addr.family = AF_UNSPEC;
memset(&srv_addr.addr, 0, sizeof(srv_addr.addr));
server_set_inetaddr(s, &srv_addr, SERVER_INETADDR_UPDATER_NONE, NULL);
}
@ -4610,6 +4611,7 @@ int snr_resolution_cb(struct resolv_requester *requester, struct dns_counters *c
/* unset server's addr, keep port */
server_get_inetaddr(s, &srv_addr);
srv_addr.family = AF_UNSPEC;
memset(&srv_addr.addr, 0, sizeof(srv_addr.addr));
server_set_inetaddr(s, &srv_addr, SERVER_INETADDR_UPDATER_NONE, NULL);
}
@ -4697,6 +4699,7 @@ int snr_resolution_error_cb(struct resolv_requester *requester, int error_code)
/* unset server's addr, keep port */
server_get_inetaddr(s, &srv_addr);
srv_addr.family = AF_UNSPEC;
memset(&srv_addr.addr, 0, sizeof(srv_addr.addr));
server_set_inetaddr(s, &srv_addr, SERVER_INETADDR_UPDATER_NONE, NULL);
HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);