Blame SOURCES/bz1665211-1-totemip-Use-AF_UNSPEC-for-ipv4-6-and-ipv6-4.patch

0794c7
From 2ab4d4188670356dcb82a80f2fc4598f5145c77d Mon Sep 17 00:00:00 2001
0794c7
From: Jan Friesse <jfriesse@redhat.com>
0794c7
Date: Thu, 10 Jan 2019 15:06:20 +0100
0794c7
Subject: [PATCH] totemip: Use AF_UNSPEC for ipv4-6 and ipv6-4
0794c7
0794c7
AF_UNSPEC returns different results than AF_INET/AF_INET6, because of
0794c7
nsswitch.conf search is in order and it stops asking other
0794c7
modules once current module success.
0794c7
0794c7
Example of difference between previous and new code when ipv6-4 is used:
0794c7
- /etc/hosts contains test_name with an ipv4
0794c7
- previous code called AF_INET6 where /etc/hosts failed so other methods
0794c7
were used which may return IPv6 addr -> result was ether fail or IPv6
0794c7
address.
0794c7
- new code calls AF_UNSPEC returning IPv4 defined in /etc/hosts ->
0794c7
result is IPv4 address
0794c7
0794c7
New code behavior should solve problems caused by nss-myhostname.
0794c7
0794c7
Signed-off-by: Jan Friesse <jfriesse@redhat.com>
0794c7
Reviewed-by: Fabio M. Di Nitto <fdinitto@redhat.com>
0794c7
---
0794c7
 exec/totemip.c                   |  106 +++++++++++++++++++++++++++-----------
0794c7
 include/corosync/totem/totemip.h |    6 +-
0794c7
 man/corosync.conf.5              |    8 ++-
0794c7
 3 files changed, 83 insertions(+), 37 deletions(-)
0794c7
0794c7
diff --git a/exec/totemip.c b/exec/totemip.c
0794c7
index 9d96e1b..36d0a72 100644
0794c7
--- a/exec/totemip.c
0794c7
+++ b/exec/totemip.c
0794c7
@@ -1,5 +1,5 @@
0794c7
 /*
0794c7
- * Copyright (c) 2005-2011 Red Hat, Inc.
0794c7
+ * Copyright (c) 2005-2019 Red Hat, Inc.
0794c7
  *
0794c7
  * All rights reserved.
0794c7
  *
0794c7
@@ -288,69 +288,113 @@ int totemip_parse(struct totem_ip_address *totemip, const char *addr,
0794c7
     enum totem_ip_version_enum ip_version)
0794c7
 {
0794c7
 	struct addrinfo *ainfo;
0794c7
+	struct addrinfo *ainfo_iter;
0794c7
+	struct addrinfo *ainfo_ipv4;
0794c7
+	struct addrinfo *ainfo_ipv6;
0794c7
+	struct addrinfo *ainfo_final;
0794c7
 	struct addrinfo ahints;
0794c7
 	struct sockaddr_in *sa;
0794c7
 	struct sockaddr_in6 *sa6;
0794c7
 	int ret;
0794c7
 	int debug_ip_family;
0794c7
-	int ai_family1, ai_family2;
0794c7
+	int ai_family;
0794c7
 
0794c7
 	memset(&ahints, 0, sizeof(ahints));
0794c7
 	ahints.ai_socktype = SOCK_DGRAM;
0794c7
 	ahints.ai_protocol = IPPROTO_UDP;
0794c7
 
0794c7
-	ai_family1 = ai_family2 = -1;
0794c7
+	ai_family = AF_UNSPEC;
0794c7
+	debug_ip_family = 0;
0794c7
 
0794c7
 	switch (ip_version) {
0794c7
 	case TOTEM_IP_VERSION_4:
0794c7
-		ai_family1 = AF_INET;
0794c7
+		ai_family = AF_INET;
0794c7
+		debug_ip_family = 4;
0794c7
 		break;
0794c7
 	case TOTEM_IP_VERSION_6:
0794c7
-		ai_family1 = AF_INET6;
0794c7
-		break;
0794c7
-	case TOTEM_IP_VERSION_4_6:
0794c7
-		ai_family1 = AF_INET;
0794c7
-		ai_family2 = AF_INET6;
0794c7
+		ai_family = AF_INET6;
0794c7
+		debug_ip_family = 6;
0794c7
 		break;
0794c7
 	case TOTEM_IP_VERSION_6_4:
0794c7
-		ai_family1 = AF_INET6;
0794c7
-		ai_family2 = AF_INET;
0794c7
+	case TOTEM_IP_VERSION_4_6:
0794c7
+		/*
0794c7
+		 * ai_family and debug_ip_family are already set correctly
0794c7
+		 */
0794c7
 		break;
0794c7
 	}
0794c7
 
0794c7
-	ahints.ai_family = ai_family1;
0794c7
+	ahints.ai_family = ai_family;
0794c7
+
0794c7
 	ret = getaddrinfo(addr, NULL, &ahints, &ainfo);
0794c7
-	if (ret && ai_family2 != -1) {
0794c7
-		ahints.ai_family = ai_family2;
0794c7
-		ret = getaddrinfo(addr, NULL, &ahints, &ainfo);
0794c7
-	}
0794c7
 
0794c7
-	debug_ip_family = 4;
0794c7
-	if (ahints.ai_family == AF_INET6) {
0794c7
-		debug_ip_family = 6;
0794c7
-	}
0794c7
+	if (ret == 0 && ai_family == AF_UNSPEC) {
0794c7
+		ainfo_ipv4 = ainfo_ipv6 = NULL;
0794c7
 
0794c7
-	if (ret) {
0794c7
-		log_printf (LOGSYS_LEVEL_DEBUG, "totemip_parse: IPv%u address of %s not resolvable",
0794c7
-		    debug_ip_family, addr);
0794c7
+		/*
0794c7
+		 * Walk thru results and store first AF_INET and AF_INET6
0794c7
+		 */
0794c7
+		for (ainfo_iter = ainfo; ainfo_iter != NULL; ainfo_iter = ainfo_iter->ai_next) {
0794c7
+			if (ainfo_iter->ai_family == AF_INET && ainfo_ipv4 == NULL) {
0794c7
+				ainfo_ipv4 = ainfo_iter;
0794c7
+			}
0794c7
 
0794c7
-		return -1;
0794c7
+			if (ainfo_iter->ai_family == AF_INET6 && ainfo_ipv6 == NULL) {
0794c7
+				ainfo_ipv6 = ainfo_iter;
0794c7
+			}
0794c7
+		}
0794c7
+
0794c7
+		if (ip_version == TOTEM_IP_VERSION_6_4) {
0794c7
+			if (ainfo_ipv6 != NULL) {
0794c7
+				ainfo_final = ainfo_ipv6;
0794c7
+			} else {
0794c7
+				ainfo_final = ainfo_ipv4;
0794c7
+			}
0794c7
+		} else {
0794c7
+			if (ainfo_ipv4 != NULL) {
0794c7
+				ainfo_final = ainfo_ipv4;
0794c7
+			} else {
0794c7
+				ainfo_final = ainfo_ipv6;
0794c7
+			}
0794c7
+		}
0794c7
+	} else if (ret == 0) {
0794c7
+		ainfo_final = ainfo;
0794c7
+	} else {
0794c7
+		ainfo_final = NULL;
0794c7
 	}
0794c7
 
0794c7
-	sa = (struct sockaddr_in *)ainfo->ai_addr;
0794c7
-	sa6 = (struct sockaddr_in6 *)ainfo->ai_addr;
0794c7
-	totemip->family = ainfo->ai_family;
0794c7
+	if (ainfo_final == NULL) {
0794c7
+		if (ret == 0) {
0794c7
+			freeaddrinfo(ainfo);
0794c7
+		}
0794c7
+
0794c7
+		if (debug_ip_family == 0) {
0794c7
+			log_printf(LOGSYS_LEVEL_DEBUG, "totemip_parse: IP address of %s not resolvable",
0794c7
+			    addr);
0794c7
+		} else {
0794c7
+			log_printf(LOGSYS_LEVEL_DEBUG, "totemip_parse: IPv%u address of %s not resolvable",
0794c7
+			    debug_ip_family, addr);
0794c7
+		}
0794c7
+
0794c7
+		return (-1);
0794c7
+	}
0794c7
 
0794c7
-	if (ainfo->ai_family == AF_INET)
0794c7
+	totemip->family = ainfo_final->ai_family;
0794c7
+	if (ainfo_final->ai_family == AF_INET) {
0794c7
+		sa = (struct sockaddr_in *)ainfo_final->ai_addr;
0794c7
 		memcpy(totemip->addr, &sa->sin_addr, sizeof(struct in_addr));
0794c7
-	else
0794c7
+		debug_ip_family = 4;
0794c7
+	} else {
0794c7
+		sa6 = (struct sockaddr_in6 *)ainfo_final->ai_addr;
0794c7
 		memcpy(totemip->addr, &sa6->sin6_addr, sizeof(struct in6_addr));
0794c7
+		debug_ip_family = 6;
0794c7
+	}
0794c7
 
0794c7
-	log_printf (LOGSYS_LEVEL_DEBUG, "totemip_parse: IPv%u address of %s resolved as %s",
0794c7
+	log_printf(LOGSYS_LEVEL_DEBUG, "totemip_parse: IPv%u address of %s resolved as %s",
0794c7
 		    debug_ip_family, addr, totemip_print(totemip));
0794c7
 
0794c7
 	freeaddrinfo(ainfo);
0794c7
-	return 0;
0794c7
+
0794c7
+	return (0);
0794c7
 }
0794c7
 
0794c7
 /* Make a sockaddr_* into a totem_ip_address */
0794c7
diff --git a/include/corosync/totem/totemip.h b/include/corosync/totem/totemip.h
0794c7
index de22461..b8da3c9 100644
0794c7
--- a/include/corosync/totem/totemip.h
0794c7
+++ b/include/corosync/totem/totemip.h
0794c7
@@ -1,5 +1,5 @@
0794c7
 /*
0794c7
- * Copyright (c) 2005-2010 Red Hat, Inc.
0794c7
+ * Copyright (c) 2005-2019 Red Hat, Inc.
0794c7
  *
0794c7
  * All rights reserved.
0794c7
  *
0794c7
@@ -70,8 +70,8 @@ struct totem_ip_address
0794c7
 enum totem_ip_version_enum {
0794c7
 	TOTEM_IP_VERSION_4,		/* Use only AF_INET */
0794c7
 	TOTEM_IP_VERSION_6,		/* Use only AF_INET6 */
0794c7
-	TOTEM_IP_VERSION_4_6,		/* Use AF_INET and if it fails, use AF_INET6 */
0794c7
-	TOTEM_IP_VERSION_6_4		/* Use AF_INET6 and if it fails, use AF_INET */
0794c7
+	TOTEM_IP_VERSION_4_6,		/* Use AF_UNSPEC and filter result preferring AF_INET */
0794c7
+	TOTEM_IP_VERSION_6_4		/* Use AF_UNSPEC and filter result preferring AF_INET6 */
0794c7
 };
0794c7
 
0794c7
 struct totem_ip_if_address
0794c7
diff --git a/man/corosync.conf.5 b/man/corosync.conf.5
0794c7
index 790f434..0e752bc 100644
0794c7
--- a/man/corosync.conf.5
0794c7
+++ b/man/corosync.conf.5
0794c7
@@ -32,7 +32,7 @@
0794c7
 .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
0794c7
 .\" * THE POSSIBILITY OF SUCH DAMAGE.
0794c7
 .\" */
0794c7
-.TH COROSYNC_CONF 5 2018-12-14 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
0794c7
+.TH COROSYNC_CONF 5 2019-01-10 "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
0794c7
 .SH NAME
0794c7
 corosync.conf - corosync executive configuration file
0794c7
 
0794c7
@@ -314,9 +314,11 @@ The value can be one of
0794c7
 (check only IPv6 address)
0794c7
 ,
0794c7
 .B ipv4-6
0794c7
-(first check IPv4 address, if that fails then look for an IPv6 address) and
0794c7
+(look for all address families and use first IPv4 address found in the list if there is such address,
0794c7
+otherwise use first IPv6 address) and
0794c7
 .B ipv6-4
0794c7
-(first check IPv6 address, if that fails then look for an IPv4 address).
0794c7
+(look for all address families and use first IPv6 address found in the list if there is such address,
0794c7
+otherwise use first IPv4 address).
0794c7
 
0794c7
 Default (if unspecified) is ipv6-4 for knet and udpu transports and ipv4 for udp.
0794c7
 
0794c7
-- 
0794c7
1.7.1
0794c7