Commit 042512aa authored by Moti Cohen's avatar Moti Cohen Committed by Oran Agra
Browse files

Fix sentinel function that compares hostnames (if failed resolve) (#11419)

Funcion sentinelAddrEqualsHostname() of sentinel makes DNS resolve
and based on it determines if two IP addresses are equal. Now, If the
DNS resolve command fails, the function simply returns 0, even if the
hostnames are identical.

This might become an issue in case of failover such that sentinel might
receives from Redis instance, response to regular INFO query it sent,
and wrongly decide that the instance is pointing to is different leader
than the one recorded because of this function, yet hostnames are
identical. In turn sentinel disconnects the connection between sentinel
and valid slave which leads to -failover-abort-no-good-slave.
See issue #11241.

I managed to reproduce only part of the flow in which the function
return wrong result and trigger +fix-slave-config.

The fix is even if the function failed to resolve then compare based on
hostnames. That is our best effort as long as the server is unavailable
for some reason. It is fine since Redis instance cannot have multiple
hostnames for a given setup

(cherry picked from commit bd23b15a)
parent 3f39c18a
...@@ -658,10 +658,16 @@ int sentinelAddrOrHostnameEqual(sentinelAddr *a, sentinelAddr *b) { ...@@ -658,10 +658,16 @@ int sentinelAddrOrHostnameEqual(sentinelAddr *a, sentinelAddr *b) {
int sentinelAddrEqualsHostname(sentinelAddr *a, char *hostname) { int sentinelAddrEqualsHostname(sentinelAddr *a, char *hostname) {
char ip[NET_IP_STR_LEN]; char ip[NET_IP_STR_LEN];
/* We always resolve the hostname and compare it to the address */ /* Try resolve the hostname and compare it to the address */
if (anetResolve(NULL, hostname, ip, sizeof(ip), if (anetResolve(NULL, hostname, ip, sizeof(ip),
sentinel.resolve_hostnames ? ANET_NONE : ANET_IP_ONLY) == ANET_ERR) sentinel.resolve_hostnames ? ANET_NONE : ANET_IP_ONLY) == ANET_ERR) {
return 0;
/* If failed resolve then compare based on hostnames. That is our best effort as
* long as the server is unavailable for some reason. It is fine since Redis
* instance cannot have multiple hostnames for a given setup */
return !strcasecmp(sentinel.resolve_hostnames ? a->hostname : a->ip, hostname);
}
/* Compare based on address */
return !strcasecmp(a->ip, ip); return !strcasecmp(a->ip, ip);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment