Commit b3abcf80 authored by Rinat Ibragimov's avatar Rinat Ibragimov Committed by Daniel Black

MDEV-6536: make --bind=hostname to listen on both IPv6 and IPv4 addresses

Binding to a hostname now makes MariaDB server to listen on all addresses
that hostname resolves to.

Rebased to 10.6 by Daniel Black

Closes: #1668
parent f691d986
......@@ -75,6 +75,15 @@ struct st_mysql_socket
/** The real socket descriptor. */
my_socket fd;
/** Is this a Unix-domain socket? */
char is_unix_domain_socket;
/** Is this a socket opened for the extra port? */
char is_extra_port;
/** Address family of the socket. (See sa_family from struct sockaddr). */
unsigned short address_family;
/**
The instrumentation hook.
Note that this hook is not conditionally defined,
......@@ -105,7 +114,7 @@ typedef struct st_mysql_socket MYSQL_SOCKET;
static inline MYSQL_SOCKET
mysql_socket_invalid()
{
MYSQL_SOCKET mysql_socket= {INVALID_SOCKET, NULL};
MYSQL_SOCKET mysql_socket= {INVALID_SOCKET, 0, 0, 0, NULL};
return mysql_socket;
}
......
CREATE TABLE t (a TEXT);
connect con1,localhost,root,,test;
SELECT * FROM t;
a
connect con2,127.0.0.1,root,,test;
SELECT * FROM t;
a
connect con3,::1,root,,test;
SELECT * FROM t;
a
connection default;
DROP TABLE t;
disconnect con1;
disconnect con2;
disconnect con3;
--source include/check_ipv6.inc
--source include/not_embedded.inc
# The server is started with --bind-address=localhost, and should
# listen on all addresses 'localhost' resolves to. With at least
# 127.0.0.1 and ::1 amongst them.
CREATE TABLE t (a TEXT);
--connect(con1,localhost,root,,test)
SELECT * FROM t;
--connect(con2,127.0.0.1,root,,test)
SELECT * FROM t;
--connect(con3,::1,root,,test)
SELECT * FROM t;
--connection default
DROP TABLE t;
--disconnect con1
--disconnect con2
--disconnect con3
......@@ -80,15 +80,16 @@ Expect 1
1
# Characteristics of 'server_tcpip_socket' entry
# Server listening socket, TCP/IP
# There is only one entry with 'wait/io/socket/sql/server_tcpip_socket'.
# It shares the same thread id as 'wait/io/socket/sql/server_unix_socket'.
SELECT COUNT(*) = 1 AS 'Expect 1'
# There are two entries with 'wait/io/socket/sql/server_tcpip_socket',
# for [::] and for 0.0.0.0.
# They share the same thread id with 'wait/io/socket/sql/server_unix_socket'.
SELECT COUNT(*) = 2 AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';
Expect 1
1
# Get the 'server_tcpip_socket' thread id
SELECT THREAD_ID INTO @thread_id
SELECT DISTINCT THREAD_ID INTO @thread_id
FROM performance_schema.socket_instances
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';
# Check the content.
......@@ -100,6 +101,7 @@ FROM performance_schema.socket_instances
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';
Expect 1
1
1
# Characteristics of 'server_unix_socket' entry
# Server listening socket, unix domain (socket file)
# There is only one entry with 'wait/io/socket/sql/server_unix_socket'.
......@@ -123,12 +125,12 @@ WHERE EVENT_NAME = 'wait/io/socket/sql/server_unix_socket';
Expect 1
1
# Server listening sockets (TCP and Unix) are handled on the same thread
SELECT COUNT(*) = 2 AS 'Expect 1'
SELECT COUNT(*) = 3 AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE THREAD_ID = @thread_id;
Expect 1
1
SELECT COUNT(*) = 2 AS 'Expect 1'
SELECT COUNT(*) = 3 AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE THREAD_ID = @thread_id;
Expect 1
......
......@@ -38,6 +38,10 @@ if($my_socket_debug)
--echo IPV6=$check_ipv6_supported, IPV4_MAPPED=$check_ipv4_mapped_supported, LOCALHOST=$my_localhost
}
# This test only runs when IPv6 is supported (see include/check_ipv6.inc), so
# the server will listen on both IPv4 and IPv6 wildcard addresses. That's why
# the expected number of TCP/IP listeners is always 2.
#
# Preserve the current state of SOCKET_INSTANCES
#
......@@ -222,17 +226,18 @@ AND PORT = 0 AND THREAD_ID = @thread_id;
--echo # Characteristics of 'server_tcpip_socket' entry
--echo # Server listening socket, TCP/IP
--echo # There is only one entry with 'wait/io/socket/sql/server_tcpip_socket'.
--echo # It shares the same thread id as 'wait/io/socket/sql/server_unix_socket'.
--echo # There are two entries with 'wait/io/socket/sql/server_tcpip_socket',
--echo # for [::] and for 0.0.0.0.
--echo # They share the same thread id with 'wait/io/socket/sql/server_unix_socket'.
SELECT COUNT(*) = 1 AS 'Expect 1'
SELECT COUNT(*) = 2 AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';
# Store the thread id of server_tcpip_socket
--echo # Get the 'server_tcpip_socket' thread id
SELECT THREAD_ID INTO @thread_id
SELECT DISTINCT THREAD_ID INTO @thread_id
FROM performance_schema.socket_instances
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';
......@@ -288,14 +293,14 @@ WHERE EVENT_NAME = 'wait/io/socket/sql/server_unix_socket';
--disable_query_log ONCE
eval SET @thread_id = $server_tcpip_thread_id;
eval SELECT COUNT(*) = 2 AS 'Expect 1'
eval SELECT COUNT(*) = 3 AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE THREAD_ID = @thread_id;
--disable_query_log ONCE
eval SET @thread_id = $server_unix_thread_id;
eval SELECT COUNT(*) = 2 AS 'Expect 1'
eval SELECT COUNT(*) = 3 AS 'Expect 1'
FROM performance_schema.socket_instances
WHERE THREAD_ID = @thread_id;
......
......@@ -12,7 +12,7 @@ log-bin= master-bin
loose-innodb
skip-name-resolve
bind-address= ::
bind-address= *
[mysqld.2]
......@@ -38,7 +38,7 @@ report-user= root
skip-slave-start
skip-name-resolve
bind-address= ::
bind-address= *
# Directory where slaves find the dumps generated by "load data"
# on the server. The path need to have constant length otherwise
......
......@@ -22,11 +22,13 @@
#include <mswsock.h>
#include <mysql/psi/mysql_socket.h>
#include <sddl.h>
#include <vector>
#include <handle_connections_win.h>
/* From mysqld.cc */
extern MYSQL_SOCKET base_ip_sock, extra_ip_sock;
extern HANDLE hEventShutdown;
extern std::vector<MYSQL_SOCKET> listen_sockets;
#ifdef HAVE_POOL_OF_THREADS
extern PTP_CALLBACK_ENVIRON get_threadpool_win_callback_environ();
extern void tp_win_callback_prolog();
......@@ -128,6 +130,9 @@ struct Socket_Listener: public Listener
/** Client socket passed to AcceptEx() call.*/
SOCKET m_client_socket;
/** Listening socket. */
MYSQL_SOCKET m_listen_socket;
/** Buffer for sockaddrs passed to AcceptEx()/GetAcceptExSockaddrs() */
char m_buffer[2 * sizeof(sockaddr_storage) + 32];
......@@ -162,7 +167,8 @@ struct Socket_Listener: public Listener
*/
Socket_Listener(MYSQL_SOCKET listen_socket, PTP_CALLBACK_ENVIRON callback_environ) :
Listener((HANDLE)listen_socket.fd,0),
m_client_socket(INVALID_SOCKET)
m_client_socket(INVALID_SOCKET),
m_listen_socket(listen_socket)
{
if (callback_environ)
{
......@@ -184,7 +190,8 @@ struct Socket_Listener: public Listener
void begin_accept()
{
retry :
m_client_socket= socket(server_socket_ai_family, SOCK_STREAM, IPPROTO_TCP);
m_client_socket= socket(m_listen_socket.address_family, SOCK_STREAM,
IPPROTO_TCP);
if (m_client_socket == INVALID_SOCKET)
{
sql_perror("socket() call failed.");
......@@ -233,7 +240,6 @@ retry :
}
MYSQL_SOCKET s_client{m_client_socket};
MYSQL_SOCKET s_listen{(SOCKET)m_handle};
#ifdef HAVE_PSI_SOCKET_INTERFACE
/* Parse socket addresses buffer filled by AcceptEx(),
......@@ -246,7 +252,8 @@ retry :
&local_addr, &local_addr_len, &remote_addr, &remote_addr_len);
s_client.m_psi= PSI_SOCKET_CALL(init_socket)
(key_socket_client_connection, (const my_socket*)&s_listen.fd, remote_addr, remote_addr_len);
(key_socket_client_connection, (const my_socket*)&m_listen_socket.fd,
remote_addr, remote_addr_len);
#endif
/* Start accepting new connection. After this point, do not use
......@@ -255,7 +262,7 @@ retry :
/* Some chores post-AcceptEx() that we need to create a normal socket.*/
if (setsockopt(s_client.fd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
(char *)&s_listen.fd, sizeof(s_listen.fd)))
(char *)&m_listen_socket.fd, sizeof(m_listen_socket.fd)))
{
if (!abort_loop)
{
......@@ -265,7 +272,7 @@ retry :
}
/* Create a new connection.*/
handle_accepted_socket(s_client, s_listen);
handle_accepted_socket(s_client, m_listen_socket);
}
~Socket_Listener()
......@@ -280,14 +287,12 @@ retry :
*/
static void init_winsock_extensions()
{
SOCKET s= mysql_socket_getfd(base_ip_sock);
if (s == INVALID_SOCKET)
s= mysql_socket_getfd(extra_ip_sock);
if (s == INVALID_SOCKET)
{
if (listen_sockets.size() == 0) {
/* --skip-networking was used*/
return;
}
SOCKET s= mysql_socket_getfd(listen_sockets[0]);
GUID guid_AcceptEx= WSAID_ACCEPTEX;
GUID guid_GetAcceptExSockaddrs= WSAID_GETACCEPTEXSOCKADDRS;
......@@ -540,22 +545,24 @@ static void create_shutdown_event()
*/
#define MAX_WAIT_HANDLES 32
#define NUM_PIPE_LISTENERS 24
#define SHUTDOWN_IDX 0
#define LISTENER_START_IDX 1
static Listener *all_listeners[MAX_WAIT_HANDLES];
static HANDLE wait_events[MAX_WAIT_HANDLES];
static int n_listeners;
static std::vector<Listener *> all_listeners;
static std::vector<HANDLE> wait_events;
void network_init_win()
{
Socket_Listener::init_winsock_extensions();
/* Listen for TCP connections on "extra-port" (no threadpool).*/
if (extra_ip_sock.fd != INVALID_SOCKET)
all_listeners[n_listeners++]= new Socket_Listener(extra_ip_sock, 0);
for (std::vector<MYSQL_SOCKET>::iterator it= listen_sockets.begin();
it != listen_sockets.end(); ++it)
{
if (it->is_extra_port)
all_listeners.push_back(new Socket_Listener(*it, 0));
}
/* Listen for named pipe connections */
if (mysqld_unix_port[0] && !opt_bootstrap && opt_enable_named_pipe)
......@@ -564,17 +571,22 @@ void network_init_win()
Use several listeners for pipe, to reduce ERROR_PIPE_BUSY on client side.
*/
for (int i= 0; i < NUM_PIPE_LISTENERS; i++)
all_listeners[n_listeners++]= new Pipe_Listener();
all_listeners.push_back(new Pipe_Listener());
}
if (base_ip_sock.fd != INVALID_SOCKET)
for (std::vector<MYSQL_SOCKET>::iterator it= listen_sockets.begin();
it != listen_sockets.end(); ++it)
{
if (it->is_extra_port)
continue;
/* Wait for TCP connections.*/
SetFileCompletionNotificationModes((HANDLE)base_ip_sock.fd, FILE_SKIP_SET_EVENT_ON_HANDLE);
all_listeners[n_listeners++]= new Socket_Listener(base_ip_sock, get_threadpool_win_callback_environ());
SetFileCompletionNotificationModes((HANDLE)it->fd,
FILE_SKIP_SET_EVENT_ON_HANDLE);
all_listeners.push_back(
new Socket_Listener(*it, get_threadpool_win_callback_environ()));
}
if (!n_listeners && !opt_bootstrap)
if (all_listeners.size() == 0 && !opt_bootstrap)
{
sql_print_error("Either TCP connections or named pipe connections must be enabled.");
unireg_abort(1);
......@@ -586,26 +598,41 @@ void handle_connections_win()
int n_waits;
create_shutdown_event();
wait_events[SHUTDOWN_IDX]= hEventShutdown;
wait_events.push_back(hEventShutdown);
n_waits= 1;
for (int i= 0; i < n_listeners; i++)
for (int i= 0; i < all_listeners.size(); i++)
{
HANDLE wait_handle= all_listeners[i]->wait_handle();
if (wait_handle)
{
DBUG_ASSERT((i == 0) || (all_listeners[i - 1]->wait_handle() != 0));
wait_events[n_waits++]= wait_handle;
wait_events.push_back(wait_handle);
}
all_listeners[i]->begin_accept();
}
mysqld_win_set_startup_complete();
// WaitForMultipleObjects can't wait on more than MAXIMUM_WAIT_OBJECTS
// handles simultaneously. Since MAXIMUM_WAIT_OBJECTS is only 64, there is
// a theoretical possiblity of exceeding that limit on installations where
// host name resolves to a lot of addresses.
if (wait_events.size() > MAXIMUM_WAIT_OBJECTS)
{
sql_print_warning(
"Too many wait events (%lu). Some connection listeners won't be handled. "
"Try to switch \"thread-handling\" to \"pool-of-threads\" and/or disable "
"\"extra-port\".", static_cast<ulong>(wait_events.size()));
wait_events.resize(MAXIMUM_WAIT_OBJECTS);
}
for (;;)
{
DWORD idx = WaitForMultipleObjects(n_waits ,wait_events, FALSE, INFINITE);
DBUG_ASSERT((int)idx >= 0 && (int)idx < n_waits);
DBUG_ASSERT(wait_events.size() <= MAXIMUM_WAIT_OBJECTS);
DWORD idx = WaitForMultipleObjects((DWORD)wait_events.size(),
wait_events.data(), FALSE, INFINITE);
DBUG_ASSERT((int)idx >= 0 && (int)idx < (int)wait_events.size());
if (idx == SHUTDOWN_IDX)
break;
......@@ -616,7 +643,7 @@ void handle_connections_win()
mysqld_win_initiate_shutdown();
/* Cleanup */
for (int i= 0; i < n_listeners; i++)
for (size_t i= 0; i < all_listeners.size(); i++)
{
Listener *listener= all_listeners[i];
if (listener->wait_handle())
......
......@@ -338,7 +338,6 @@ static char *character_set_filesystem_name;
static char *lc_messages;
static char *lc_time_names_name;
char *my_bind_addr_str;
int server_socket_ai_family;
static char *default_collation_name;
char *default_storage_engine, *default_tmp_storage_engine;
char *enforced_storage_engine=NULL;
......@@ -1349,7 +1348,8 @@ static Buffered_logs buffered_logs;
struct my_rnd_struct sql_rand; ///< used by sql_class.cc:THD::THD()
#ifndef EMBEDDED_LIBRARY
MYSQL_SOCKET unix_sock, base_ip_sock, extra_ip_sock;
std::vector<MYSQL_SOCKET> listen_sockets;
bool unix_sock_is_online= false;
/**
Error reporter that buffer log messages.
@param level log message level
......@@ -1690,28 +1690,15 @@ static void close_connections(void)
/* Abort listening to new connections */
DBUG_PRINT("quit",("Closing sockets"));
if (!opt_disable_networking )
for (std::vector<MYSQL_SOCKET>::iterator sock = listen_sockets.begin();
sock != listen_sockets.end(); ++sock)
{
if (mysql_socket_getfd(base_ip_sock) != INVALID_SOCKET)
{
(void) mysql_socket_close(base_ip_sock);
base_ip_sock= MYSQL_INVALID_SOCKET;
}
if (mysql_socket_getfd(extra_ip_sock) != INVALID_SOCKET)
{
(void) mysql_socket_close(extra_ip_sock);
extra_ip_sock= MYSQL_INVALID_SOCKET;
}
}
#ifdef HAVE_SYS_UN_H
if (mysql_socket_getfd(unix_sock) != INVALID_SOCKET)
{
(void) mysql_socket_close(unix_sock);
(void) mysql_socket_close(*sock);
if (sock->is_unix_domain_socket)
(void) unlink(mysqld_unix_port);
unix_sock= MYSQL_INVALID_SOCKET;
}
#endif
listen_sockets.clear();
end_thr_alarm(0); // Abort old alarms.
/*
......@@ -1800,13 +1787,20 @@ static void close_server_sock()
#ifdef HAVE_CLOSE_SERVER_SOCK
DBUG_ENTER("close_server_sock");
close_socket(base_ip_sock, "TCP/IP");
close_socket(extra_ip_sock, "TCP/IP");
close_socket(unix_sock, "unix/IP");
if (mysql_socket_getfd(unix_sock) != INVALID_SOCKET)
for (std::vector<MYSQL_SOCKET>::iterator sock= listen_sockets.begin();
sock != listen_sockets.end(); ++sock)
{
if (sock->is_unix_domain_socket)
{
close_socket(*sock, "unix/IP");
(void) unlink(mysqld_unix_port);
base_ip_sock= extra_ip_sock= unix_sock= MYSQL_INVALID_SOCKET;
}
else
{
close_socket(*sock, "TCP/IP");
}
}
listen_sockets.clear();
DBUG_VOID_RETURN;
#endif
......@@ -2241,7 +2235,9 @@ static void set_root(const char *path)
Activate usage of a tcp port
*/
static MYSQL_SOCKET activate_tcp_port(uint port)
static void activate_tcp_port(uint port,
std::vector<MYSQL_SOCKET> *listen_sockets,
bool is_extra_port= false)
{
struct addrinfo *ai, *a;
struct addrinfo hints;
......@@ -2273,20 +2269,6 @@ static MYSQL_SOCKET activate_tcp_port(uint port)
unireg_abort(1); /* purecov: tested */
}
/*
special case: for wildcard addresses prefer ipv6 over ipv4,
because we later switch off IPV6_V6ONLY, so ipv6 wildcard
addresses will work for ipv4 too
*/
if (!real_bind_addr_str && ai->ai_family == AF_INET && ai->ai_next
&& ai->ai_next->ai_family == AF_INET6)
{
a= ai;
ai= ai->ai_next;
a->ai_next= ai->ai_next;
ai->ai_next= a;
}
for (a= ai; a != NULL; a= a->ai_next)
{
ip_sock= mysql_socket_socket(key_socket_tcpip, a->ai_family,
......@@ -2309,12 +2291,9 @@ static MYSQL_SOCKET activate_tcp_port(uint port)
}
else
{
server_socket_ai_family= a->ai_family;
ip_sock.address_family= a->ai_family;
sql_print_information("Server socket created on IP: '%s'.",
(const char *) ip_addr);
break;
}
}
if (mysql_socket_getfd(ip_sock) == INVALID_SOCKET)
{
......@@ -2331,23 +2310,20 @@ static MYSQL_SOCKET activate_tcp_port(uint port)
user to open two mysqld servers with the same TCP/IP port.
*/
arg= 1;
(void) mysql_socket_setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,
sizeof(arg));
(void) mysql_socket_setsockopt(ip_sock, SOL_SOCKET, SO_REUSEADDR,
(char*)&arg, sizeof(arg));
#endif /* __WIN__ */
#ifdef IPV6_V6ONLY
/*
For interoperability with older clients, IPv6 socket should
listen on both IPv6 and IPv4 wildcard addresses.
Turn off IPV6_V6ONLY option.
NOTE: this will work starting from Windows Vista only.
On Windows XP dual stack is not available, so it will not
listen on the corresponding IPv4-address.
If an address name resolves to both IPv4 and IPv6 addresses, the server
will listen on them both. With IPV6_V6ONLY unset, listening on an IPv6
wildcard address may cause listening on an IPv4 wildcard address
to fail. That's why IPV6_V6ONLY needs to be forcefully turned on.
*/
if (a->ai_family == AF_INET6)
{
arg= 0;
arg= 1;
(void) mysql_socket_setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY,
(char*)&arg, sizeof(arg));
}
......@@ -2355,8 +2331,8 @@ static MYSQL_SOCKET activate_tcp_port(uint port)
#ifdef IP_FREEBIND
arg= 1;
(void) mysql_socket_setsockopt(ip_sock, IPPROTO_IP, IP_FREEBIND, (char*) &arg,
sizeof(arg));
(void) mysql_socket_setsockopt(ip_sock, IPPROTO_IP, IP_FREEBIND,
(char*) &arg, sizeof(arg));
#endif
/*
Sometimes the port is not released fast enough when stopping and
......@@ -2370,15 +2346,15 @@ static MYSQL_SOCKET activate_tcp_port(uint port)
uint waited, retry, this_wait;
for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
{
if (((ret= mysql_socket_bind(ip_sock, a->ai_addr, a->ai_addrlen)) >= 0 ) ||
(socket_errno != SOCKET_EADDRINUSE) ||
(waited >= mysqld_port_timeout))
if (((ret= mysql_socket_bind(ip_sock, a->ai_addr, a->ai_addrlen)) >= 0 )
|| (socket_errno != SOCKET_EADDRINUSE)
|| (waited >= mysqld_port_timeout))
break;
sql_print_information("Retrying bind on TCP/IP port %u", port);
this_wait= retry * retry / 3 + 1;
sleep(this_wait);
}
freeaddrinfo(ai);
if (ret < 0)
{
char buff[100];
......@@ -2400,8 +2376,13 @@ static MYSQL_SOCKET activate_tcp_port(uint port)
#ifdef FD_CLOEXEC
(void) fcntl(mysql_socket_getfd(ip_sock), F_SETFD, FD_CLOEXEC);
#endif
ip_sock.is_extra_port= is_extra_port;
listen_sockets->push_back(ip_sock);
}
}
DBUG_RETURN(ip_sock);
freeaddrinfo(ai);
DBUG_VOID_RETURN;
}
static void network_init(void)
......@@ -2431,9 +2412,11 @@ static void network_init(void)
if (!opt_disable_networking && !opt_bootstrap)
{
if (mysqld_port)
base_ip_sock= activate_tcp_port(mysqld_port);
activate_tcp_port(mysqld_port, &listen_sockets,
/* is_extra_port= */ false);
if (mysqld_extra_port)
extra_ip_sock= activate_tcp_port(mysqld_extra_port);
activate_tcp_port(mysqld_extra_port, &listen_sockets,
/* is_extra_port= */ true);
}
#if defined(HAVE_SYS_UN_H)
......@@ -2442,6 +2425,7 @@ static void network_init(void)
*/
if (mysqld_unix_port[0] && !opt_bootstrap)
{
MYSQL_SOCKET unix_sock= MYSQL_INVALID_SOCKET;
size_t port_len;
DBUG_PRINT("general",("UNIX Socket is %s",mysqld_unix_port));
......@@ -2458,6 +2442,9 @@ static void network_init(void)
unireg_abort(1); /* purecov: inspected */
}
unix_sock.is_unix_domain_socket= true;
listen_sockets.push_back(unix_sock);
unix_sock_is_online= true;
mysql_socket_set_thread_owner(unix_sock);
bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
......@@ -5645,8 +5632,7 @@ int mysqld_main(int argc, char **argv)
if (IS_SYSVAR_AUTOSIZE(&server_version_ptr))
sql_print_information(ER_DEFAULT(ER_STARTUP), my_progname, server_version,
((mysql_socket_getfd(unix_sock) == INVALID_SOCKET) ?
(char*) "" : mysqld_unix_port),
(unix_sock_is_online ? mysqld_unix_port : (char*) ""),
mysqld_port, MYSQL_COMPILATION_COMMENT);
else
{
......@@ -5658,8 +5644,7 @@ int mysqld_main(int argc, char **argv)
sql_print_information(ER_DEFAULT(ER_STARTUP), my_progname,
real_server_version,
((mysql_socket_getfd(unix_sock) == INVALID_SOCKET) ?
(char*) "" : mysqld_unix_port),
(unix_sock_is_online ? mysqld_unix_port : (char*) ""),
mysqld_port, MYSQL_COMPILATION_COMMENT);
}
......@@ -5866,8 +5851,7 @@ void handle_accepted_socket(MYSQL_SOCKET new_sock, MYSQL_SOCKET sock)
{
#ifdef HAVE_LIBWRAP
{
if (mysql_socket_getfd(sock) == mysql_socket_getfd(base_ip_sock) ||
mysql_socket_getfd(sock) == mysql_socket_getfd(extra_ip_sock))
if (!sock.is_unix_domain_socket)
{
struct request_info req;
signal(SIGCHLD, SIG_DFL);
......@@ -5910,11 +5894,9 @@ void handle_accepted_socket(MYSQL_SOCKET new_sock, MYSQL_SOCKET sock)
DBUG_PRINT("info", ("Creating CONNECT for new connection"));
if (auto connect= new CONNECT(new_sock,
mysql_socket_getfd(sock) ==
mysql_socket_getfd(unix_sock) ?
sock.is_unix_domain_socket ?
VIO_TYPE_SOCKET : VIO_TYPE_TCPIP,
mysql_socket_getfd(sock) ==
mysql_socket_getfd(extra_ip_sock) ?
sock.is_extra_port ?
extra_thread_scheduler : thread_scheduler))
create_new_thread(connect);
else
......@@ -5950,36 +5932,30 @@ void handle_connections_sockets()
struct sockaddr_storage cAddr;
int retval;
#ifdef HAVE_POLL
int socket_count= 0;
struct pollfd fds[3]; // for ip_sock, unix_sock and extra_ip_sock
MYSQL_SOCKET pfs_fds[3]; // for performance schema
#define setup_fds(X) \
mysql_socket_set_thread_owner(X); \
pfs_fds[socket_count]= (X); \
fds[socket_count].fd= mysql_socket_getfd(X); \
fds[socket_count].events= POLLIN; \
socket_count++
std::vector<struct pollfd> fds; // for ip_sock, unix_sock and extra_ip_sock
#else
#define setup_fds(X) FD_SET(mysql_socket_getfd(X),&clientFDs)
fd_set readFDs,clientFDs;
FD_ZERO(&clientFDs);
#endif
DBUG_ENTER("handle_connections_sockets");
if (mysql_socket_getfd(base_ip_sock) != INVALID_SOCKET)
#ifdef HAVE_POLL
fds.resize(listen_sockets.size());
for (size_t i= 0; i < listen_sockets.size(); i++)
{
setup_fds(base_ip_sock);
set_non_blocking_if_supported(base_ip_sock);
mysql_socket_set_thread_owner(listen_sockets[i]);
fds[i].fd= mysql_socket_getfd(listen_sockets[i]);
fds[i].events= POLLIN;
set_non_blocking_if_supported(listen_sockets[i]);
}
if (mysql_socket_getfd(extra_ip_sock) != INVALID_SOCKET)
#else
FD_ZERO(&clientFDs);
for (size_t i= 0; i < listen_sockets.size(); i++)
{
setup_fds(extra_ip_sock);
set_non_blocking_if_supported(extra_ip_sock);
int fd= mysql_socket_getfd(listen_sockets[i]);
FD_SET(fd, &clientFDs);
set_non_blocking_if_supported(listen_sockets[i]);
}
#ifdef HAVE_SYS_UN_H
setup_fds(unix_sock);
set_non_blocking_if_supported(unix_sock);
#endif
sd_notify(0, "READY=1\n"
......@@ -5989,10 +5965,10 @@ void handle_connections_sockets()
while (!abort_loop)
{
#ifdef HAVE_POLL
retval= poll(fds, socket_count, -1);
retval= poll(fds.data(), fds.size(), -1);
#else
readFDs=clientFDs;
retval= select((int) 0,&readFDs,0,0,0);
retval= select(FD_SETSIZE, &readFDs, NULL, NULL, NULL);
#endif
if (retval < 0)
......@@ -6016,22 +5992,23 @@ void handle_connections_sockets()
/* Is this a new connection request ? */
#ifdef HAVE_POLL
for (int i= 0; i < socket_count; ++i)
for (size_t i= 0; i < fds.size(); ++i)
{
if (fds[i].revents & POLLIN)
{
sock= pfs_fds[i];
sock= listen_sockets[i];
break;
}
}
#else // HAVE_POLL
if (FD_ISSET(mysql_socket_getfd(base_ip_sock),&readFDs))
sock= base_ip_sock;
else
if (FD_ISSET(mysql_socket_getfd(extra_ip_sock),&readFDs))
sock= extra_ip_sock;
else
sock = unix_sock;
for (size_t i=0; i < listen_sockets.size(); i++)
{
if (FD_ISSET(mysql_socket_getfd(listen_sockets[i]), &readFDs))
{
sock= listen_sockets[i];
break;
}
}
#endif // HAVE_POLL
for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++)
......@@ -7514,9 +7491,6 @@ static int mysql_init_variables(void)
character_set_filesystem= &my_charset_bin;
opt_specialflag= SPECIAL_ENGLISH;
#ifndef EMBEDDED_LIBRARY
unix_sock= base_ip_sock= extra_ip_sock= MYSQL_INVALID_SOCKET;
#endif
mysql_home_ptr= mysql_home;
log_error_file_ptr= log_error_file;
protocol_version= PROTOCOL_VERSION;
......
......@@ -147,7 +147,6 @@ extern ulong opt_replicate_events_marked_for_skip;
extern char *default_tz_name;
extern Time_zone *default_tz;
extern char *my_bind_addr_str;
extern int server_socket_ai_family;
extern char *default_storage_engine, *default_tmp_storage_engine;
extern char *enforced_storage_engine;
extern char *gtid_pos_auto_engines;
......
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