summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2019-12-24 17:22:45 +0000
committerVladislav Vaintroub <wlad@mariadb.com>2019-12-24 17:22:45 +0000
commit4eefb802e4a939e53c0a818e789d2b72cdb96b1e (patch)
treec5b5785a4fea05d6f3ec3a3ccf41fa89130dd891
parent523879dd51c3bf2ad23295852304531d856cc869 (diff)
downloadmariadb-git-10.5-windows-afunix.tar.gz
Support AF_UNIX socket on Windows10.5-windows-afunix
-rw-r--r--sql/handle_connections_win.cc147
-rw-r--r--sql/threadpool_win.cc1
2 files changed, 130 insertions, 18 deletions
diff --git a/sql/handle_connections_win.cc b/sql/handle_connections_win.cc
index 3b29ad439ac..85f5702e828 100644
--- a/sql/handle_connections_win.cc
+++ b/sql/handle_connections_win.cc
@@ -14,14 +14,15 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
/* Accepting connections on Windows */
-
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <afunix.h>
#include <my_global.h>
-#include <sql_class.h>
-#include <sql_connect.h>
-#include <mysqld.h>
-#include <mswsock.h>
#include <mysql/psi/mysql_socket.h>
+#include <mysqld.h>
#include <sddl.h>
+#include <sql_class.h>
+#include <sql_connect.h>
#include <handle_connections_win.h>
@@ -116,6 +117,92 @@ struct Listener
static LPFN_ACCEPTEX my_AcceptEx;
static LPFN_GETACCEPTEXSOCKADDRS my_GetAcceptExSockaddrs;
+extern MYSQL_SOCKET unix_sock;
+HANDLE unix_sock_handle;
+
+bool is_afunix_socket(const char* path)
+{
+ WIN32_FIND_DATA find_data;
+
+ HANDLE hFind= FindFirstFile(path, &find_data);
+ if (hFind == INVALID_HANDLE_VALUE)
+ return false;
+ FindClose(hFind);
+
+ if (!(find_data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT))
+ return false;
+
+ return find_data.dwReserved0 == IO_REPARSE_TAG_AF_UNIX;
+}
+
+#include <windows.h>
+#include <AclAPI.h>
+MYSQL_SOCKET create_afunix_socket(const char *path)
+{
+ // Create a AF_UNIX stream server socket.
+ MYSQL_SOCKET listen_socket= mysql_socket_invalid();
+ listen_socket.fd= socket(AF_UNIX, SOCK_STREAM, 0);
+ if (listen_socket.fd == INVALID_SOCKET)
+ return listen_socket;
+
+ SOCKADDR_UN sock_addr_un= {};
+ sock_addr_un.sun_family= AF_UNIX;
+ if (strlen(path) > sizeof(sock_addr_un.sun_path))
+ {
+ sql_print_error("The socket file path is too long (> %u): %s",
+ (uint) sizeof(sock_addr_un.sun_path) - 1,
+ mysqld_unix_port);
+ return listen_socket;
+ }
+ strcpy(sock_addr_un.sun_path, path);
+
+#if 0
+ // Abstract socket does not work yet,
+ // https://github.com/microsoft/WSL/issues/4240
+ if (path[0] == '@')
+ {
+ sock_addr_un.sun_path[0]= 0;
+ }
+#endif
+
+
+ DeleteFile(path);
+
+ // Bind the socket to the path
+ int res= bind(listen_socket.fd, (struct sockaddr *) &sock_addr_un,
+ sizeof(sock_addr_un));
+ if (res == SOCKET_ERROR)
+ {
+ sql_perror("bind AF_UNIX socket failed");
+ closesocket(listen_socket.fd);
+ return mysql_socket_invalid();
+ }
+ PSECURITY_DESCRIPTOR sd;
+ if (!ConvertStringSecurityDescriptorToSecurityDescriptorA(
+ "S:(ML;; NW;;; LW) D:(A;; FA;;; WD)", 1, &sd, NULL))
+ {
+ sql_perror("Can't start server : Initialize security descriptor");
+ unireg_abort(1);
+ }
+ if (!SetFileSecurityA(path, DACL_SECURITY_INFORMATION, sd))
+ {
+ sql_perror("SetFileSecurity() failed on unix socket");
+ unireg_abort(1);
+ }
+ LocalFree(sd);
+ if (mysql_socket_listen(listen_socket, (int) back_log) < 0)
+ {
+ sql_print_warning("listen() on Unix socket failed with error %d",
+ socket_errno);
+ closesocket(listen_socket.fd);
+ return mysql_socket_invalid();
+ }
+
+ unix_sock= listen_socket;
+ return listen_socket;
+}
+
+
/**
Listener that handles socket connections.
Can be threadpool-bound (i.e the completion is executed in threadpool thread),
@@ -128,6 +215,7 @@ struct Socket_Listener: public Listener
{
/** Client socket passed to AcceptEx() call.*/
SOCKET m_client_socket;
+ int m_ai_family;
/** Buffer for sockaddrs passed to AcceptEx()/GetAcceptExSockaddrs() */
char m_buffer[2 * sizeof(sockaddr_storage) + 32];
@@ -161,8 +249,9 @@ struct Socket_Listener: public Listener
@PTP_CALLBACK_ENVIRON callback_environ - threadpool environment, or NULL
if threadpool is not used for completion callbacks.
*/
- Socket_Listener(MYSQL_SOCKET listen_socket, PTP_CALLBACK_ENVIRON callback_environ) :
+ Socket_Listener(MYSQL_SOCKET listen_socket, int ai_family,PTP_CALLBACK_ENVIRON callback_environ) :
Listener((HANDLE)listen_socket.fd,0),
+ m_ai_family(ai_family),
m_client_socket(INVALID_SOCKET)
{
if (callback_environ)
@@ -184,8 +273,8 @@ struct Socket_Listener: public Listener
*/
void begin_accept()
{
-retry :
- m_client_socket= socket(server_socket_ai_family, SOCK_STREAM, IPPROTO_TCP);
+ retry:
+ m_client_socket= socket(m_ai_family, SOCK_STREAM, 0);
if (m_client_socket == INVALID_SOCKET)
{
sql_perror("socket() call failed.");
@@ -280,14 +369,15 @@ 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)
+ SOCKET s= INVALID_SOCKET;
+ for (auto sock : {base_ip_sock, extra_ip_sock, unix_sock})
{
- /* --skip-networking was used*/
- return;
+ if ((s= mysql_socket_getfd(sock)) != INVALID_SOCKET)
+ break;
}
+ if (s == INVALID_SOCKET)
+ return; // No sockets
+
GUID guid_AcceptEx= WSAID_ACCEPTEX;
GUID guid_GetAcceptExSockaddrs= WSAID_GETACCEPTEXSOCKADDRS;
@@ -481,6 +571,8 @@ struct Pipe_Listener : public Listener
#define SHUTDOWN_IDX 0
#define LISTENER_START_IDX 1
+
+
void handle_connections_win()
{
Listener* all_listeners[MAX_WAIT_HANDLES]= {};
@@ -488,11 +580,17 @@ void handle_connections_win()
int n_listeners= 0;
int n_waits= 0;
+ if (mysqld_unix_port[0] && !opt_bootstrap && opt_enable_named_pipe)
+ {
+ unix_sock = create_afunix_socket(mysqld_unix_port);
+ }
+
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);
+ all_listeners[n_listeners++]=
+ new Socket_Listener(extra_ip_sock, server_socket_ai_family, 0);
/* Listen for named pipe connections */
if (mysqld_unix_port[0] && !opt_bootstrap && opt_enable_named_pipe)
@@ -502,13 +600,26 @@ void handle_connections_win()
*/
for (int i= 0; i < NUM_PIPE_LISTENERS; i++)
all_listeners[n_listeners++]= new Pipe_Listener();
+
+
+ if (unix_sock.fd != INVALID_SOCKET)
+ {
+ /* Wait for Unix socket connections.*/
+ SetFileCompletionNotificationModes((HANDLE) unix_sock.fd,
+ FILE_SKIP_SET_EVENT_ON_HANDLE);
+ all_listeners[n_listeners++]= new Socket_Listener(
+ unix_sock, AF_UNIX, get_threadpool_win_callback_environ());
+ }
}
if (base_ip_sock.fd != INVALID_SOCKET)
{
- /* 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());
+ /* 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, server_socket_ai_family,
+ get_threadpool_win_callback_environ());
}
if (!n_listeners && !opt_bootstrap)
diff --git a/sql/threadpool_win.cc b/sql/threadpool_win.cc
index c9968d48c06..220df063cb0 100644
--- a/sql/threadpool_win.cc
+++ b/sql/threadpool_win.cc
@@ -146,6 +146,7 @@ int TP_connection_win::init()
{
case VIO_TYPE_SSL:
case VIO_TYPE_TCPIP:
+ case VIO_TYPE_SOCKET:
handle= (HANDLE) mysql_socket_getfd(connect->sock);
break;
case VIO_TYPE_NAMEDPIPE: