summaryrefslogtreecommitdiff
path: root/sql/wsrep_utils.cc
diff options
context:
space:
mode:
authorNirbhay Choubey <nirbhay@mariadb.com>2015-09-15 18:58:08 -0400
committerNirbhay Choubey <nirbhay@mariadb.com>2015-09-15 18:58:08 -0400
commitbb52905432779d1648241baa5945c61617f2d58f (patch)
tree369b6c90366e3c8add210d0367e2d0cc05fcff7e /sql/wsrep_utils.cc
parent31cf362c21b24ebda9d3997a401750ec94a19d5c (diff)
downloadmariadb-git-bb52905432779d1648241baa5945c61617f2d58f.tar.gz
MDEV-8034 : wsrep_node_address can't be IPV6
Updated address parsing logic to include IPv6 format.
Diffstat (limited to 'sql/wsrep_utils.cc')
-rw-r--r--sql/wsrep_utils.cc77
1 files changed, 48 insertions, 29 deletions
diff --git a/sql/wsrep_utils.cc b/sql/wsrep_utils.cc
index 7a87d38d430..80f8bd4c7d4 100644
--- a/sql/wsrep_utils.cc
+++ b/sql/wsrep_utils.cc
@@ -352,7 +352,7 @@ thd::~thd ()
} // namespace wsp
/* Returns INADDR_NONE, INADDR_ANY, INADDR_LOOPBACK or something else */
-unsigned int wsrep_check_ip (const char* const addr)
+unsigned int wsrep_check_ip (const char* const addr, bool *is_ipv6)
{
unsigned int ret = INADDR_NONE;
struct addrinfo *res, hints;
@@ -362,6 +362,8 @@ unsigned int wsrep_check_ip (const char* const addr)
hints.ai_socktype= SOCK_STREAM;
hints.ai_family= AF_UNSPEC;
+ *is_ipv6= false;
+
int gai_ret = getaddrinfo(addr, NULL, &hints, &res);
if (0 == gai_ret)
{
@@ -379,6 +381,8 @@ unsigned int wsrep_check_ip (const char* const addr)
ret= INADDR_LOOPBACK;
else
ret= 0xdeadbeef;
+
+ *is_ipv6= true;
}
freeaddrinfo (res);
}
@@ -387,10 +391,6 @@ unsigned int wsrep_check_ip (const char* const addr)
addr, gai_ret, gai_strerror(gai_ret));
}
- // uint8_t* b= (uint8_t*)&ret;
- // fprintf (stderr, "########## wsrep_check_ip returning: %hhu.%hhu.%hhu.%hhu\n",
- // b[0], b[1], b[2], b[3]);
-
return ret;
}
@@ -398,44 +398,47 @@ extern char* my_bind_addr_str;
size_t wsrep_guess_ip (char* buf, size_t buf_len)
{
- size_t ip_len = 0;
+ size_t ret= 0;
+ // Attempt 1: Try to get the IP from bind-address.
if (my_bind_addr_str && my_bind_addr_str[0] != '\0')
{
- unsigned int const ip_type= wsrep_check_ip(my_bind_addr_str);
+ bool unused;
+ unsigned int const ip_type= wsrep_check_ip(my_bind_addr_str, &unused);
if (INADDR_NONE == ip_type) {
WSREP_ERROR("Networking not configured, cannot receive state "
"transfer.");
- return 0;
- }
-
- if (INADDR_ANY != ip_type) {
+ ret= 0;
+ } else if (INADDR_ANY != ip_type) {
strncpy (buf, my_bind_addr_str, buf_len);
- return strlen(buf);
+ ret= strlen(buf);
}
+ goto done;
}
- // mysqld binds to all interfaces - try IP from wsrep_node_address
+ // Attempt 2: mysqld binds to all interfaces, try IP from wsrep_node_address.
if (wsrep_node_address && wsrep_node_address[0] != '\0') {
- const char* const colon_ptr = strchr(wsrep_node_address, ':');
-
- if (colon_ptr)
- ip_len = colon_ptr - wsrep_node_address;
- else
- ip_len = strlen(wsrep_node_address);
-
- if (ip_len >= buf_len) {
- WSREP_WARN("default_ip(): buffer too short: %zu <= %zd", buf_len, ip_len);
- return 0;
+ wsp::Address addr(wsrep_node_address);
+ if (!addr.is_valid())
+ {
+ WSREP_WARN("Could not parse wsrep_node_address : %s",
+ wsrep_node_address);
+ ret= 0;
+ goto done;
}
- memcpy (buf, wsrep_node_address, ip_len);
- buf[ip_len] = '\0';
- return ip_len;
+ /* Safety check: Buffer length should be sufficiently large. */
+ DBUG_ASSERT(buf_len >= addr.get_address_len());
+
+ memcpy(buf, addr.get_address(), addr.get_address_len());
+ ret= addr.get_address_len();
+ goto done;
}
/*
+ Attempt 3: Try to get the IP from the list of available interfaces.
+
getifaddrs() is avaiable at least on Linux since glib 2.3, FreeBSD,
MAC OSX, OpenSolaris, Solaris.
@@ -444,26 +447,42 @@ size_t wsrep_guess_ip (char* buf, size_t buf_len)
*/
#if HAVE_GETIFADDRS
struct ifaddrs *ifaddr, *ifa;
+ int family;
+
if (getifaddrs(&ifaddr) == 0)
{
for (ifa= ifaddr; ifa != NULL; ifa = ifa->ifa_next)
{
- if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET) // TODO AF_INET6
+ if (!ifa->ifa_addr)
+ continue;
+
+ family= ifa->ifa_addr->sa_family;
+
+ if ((family != AF_INET) && (family != AF_INET6))
continue;
// Skip loopback interfaces (like lo:127.0.0.1)
if (ifa->ifa_flags & IFF_LOOPBACK)
continue;
+ /*
+ Get IP address from the socket address. The resulting address may have
+ zone ID appended for IPv6 addresses (<address>%<zone-id>).
+ */
if (vio_getnameinfo(ifa->ifa_addr, buf, buf_len, NULL, 0, NI_NUMERICHOST))
continue;
freeifaddrs(ifaddr);
- return strlen(buf);
+
+ ret= strlen(buf);
+ goto done;
}
freeifaddrs(ifaddr);
}
#endif /* HAVE_GETIFADDRS */
- return 0;
+done:
+ WSREP_DEBUG("wsrep_guess_ip() : %s", (ret > 0) ? buf : "????");
+ return ret;
}
+