Commit 5ae72bb7 authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-4356 : MariaDB does not start if bind-address gets resolved to more than single IP address.

  
MySQL bug http://bugs.mysql.com/bug.php?id=61713 was fixed in 5.5
  
Fix is to remove check for multiple entries returned by getaddrinfo(), and use the first entry that works  - i.e socket can be created.  

Unlike Oracle/MySQL's fix ,this one  is kept minimal : 
-  we do not prioritize IPv4 over IPv6,  orr other way around,  and just rely on operating system to sort getaddrinfo() entries in sensible order. There is RFC that defines  what is sensible order for getaddrinfo entries ( RFC 3484), and OS specific tweaks are also possible , like /etc/gai.conf o Linux.
-  also,  we do not force "0.0.0.0" address if bind-address is not given -  this would be a change in behavior of 5.5 at least on Windows, where passing NULL as  to getaddrinfo()  gives back IPv6-wildcard.
parent ed949df1
...@@ -2164,8 +2164,28 @@ static my_socket activate_tcp_port(uint port) ...@@ -2164,8 +2164,28 @@ static my_socket activate_tcp_port(uint port)
for (a= ai; a != NULL; a= a->ai_next) for (a= ai; a != NULL; a= a->ai_next)
{ {
ip_sock= socket(a->ai_family, a->ai_socktype, a->ai_protocol); ip_sock= socket(a->ai_family, a->ai_socktype, a->ai_protocol);
if (ip_sock != INVALID_SOCKET)
char ip_addr[INET6_ADDRSTRLEN];
if (vio_get_normalized_ip_string(a->ai_addr, a->ai_addrlen,
ip_addr, sizeof (ip_addr)))
{
ip_addr[0]= 0;
}
if (ip_sock == INVALID_SOCKET)
{
sql_print_error("Failed to create a socket for %s '%s': errno: %d.",
(a->ai_family == AF_INET) ? "IPv4" : "IPv6",
(const char *) ip_addr,
(int) socket_errno);
}
else
{
sql_print_information("Server socket created on IP: '%s'.",
(const char *) ip_addr);
break; break;
}
} }
if (ip_sock == INVALID_SOCKET) if (ip_sock == INVALID_SOCKET)
...@@ -7657,28 +7677,6 @@ mysqld_get_one_option(int optid, ...@@ -7657,28 +7677,6 @@ mysqld_get_one_option(int optid,
case (int) OPT_WANT_CORE: case (int) OPT_WANT_CORE:
test_flags |= TEST_CORE_ON_SIGNAL; test_flags |= TEST_CORE_ON_SIGNAL;
break; break;
case (int) OPT_BIND_ADDRESS:
{
struct addrinfo *res_lst, hints;
bzero(&hints, sizeof(struct addrinfo));
hints.ai_socktype= SOCK_STREAM;
hints.ai_protocol= IPPROTO_TCP;
if (getaddrinfo(argument, NULL, &hints, &res_lst) != 0)
{
sql_print_error("Can't start server: cannot resolve hostname!");
return 1;
}
if (res_lst->ai_next)
{
sql_print_error("Can't start server: bind-address refers to multiple interfaces!");
return 1;
}
freeaddrinfo(res_lst);
}
break;
case OPT_CONSOLE: case OPT_CONSOLE:
if (opt_console) if (opt_console)
opt_error_log= 0; // Force logs to stdout opt_error_log= 0; // Force logs to stdout
......
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