From: Aurelien DARRAGON Date: Fri, 28 Jun 2024 07:41:56 +0000 (+0200) Subject: BUG/MEDIUM: server/dns: prevent DOWN/UP flap upon resolution timeout or error X-Git-Tag: v3.1-dev2~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=80aba1d2844165d9c6929d31cc9c2fd2e92286ed;p=thirdparty%2Fhaproxy.git 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. --- diff --git a/src/server.c b/src/server.c index d5c6318749..8bf3c595ab 100644 --- a/src/server.c +++ b/src/server.c @@ -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);