diff options
author | Nirbhay Choubey <nirbhay@mariadb.com> | 2015-09-15 18:58:08 -0400 |
---|---|---|
committer | Nirbhay Choubey <nirbhay@mariadb.com> | 2015-09-15 18:58:08 -0400 |
commit | bb52905432779d1648241baa5945c61617f2d58f (patch) | |
tree | 369b6c90366e3c8add210d0367e2d0cc05fcff7e /sql/wsrep_utils.cc | |
parent | 31cf362c21b24ebda9d3997a401750ec94a19d5c (diff) | |
download | mariadb-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.cc | 77 |
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; } + |