Move UNIX domain socket creation to utils.c
The network socket code is now completely inside utils.c.
This commit is contained in:
@ -69,6 +69,23 @@ void utils_end();
|
|||||||
int open_network_socket(enum mxs_socket_type type, struct sockaddr_storage *addr,
|
int open_network_socket(enum mxs_socket_type type, struct sockaddr_storage *addr,
|
||||||
const char *host, uint16_t port);
|
const char *host, uint16_t port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a UNIX domain socket
|
||||||
|
*
|
||||||
|
* This opens and prepares a UNIX domain socket for use. The @c addr parameter
|
||||||
|
* can be given to the bind() function to bind the socket.
|
||||||
|
*
|
||||||
|
* @param type Type of the socket, either MXS_SOCKET_LISTENER for a listener
|
||||||
|
* socket or MXS_SOCKET_NETWORK for a network connection socket
|
||||||
|
* @param addr Pointer to a struct sockaddr_un where the socket configuration
|
||||||
|
* is stored
|
||||||
|
* @param path Path to the socket
|
||||||
|
*
|
||||||
|
* @return The opened socket or -1 on failure
|
||||||
|
*/
|
||||||
|
int open_unix_socket(enum mxs_socket_type type, struct sockaddr_un *addr,
|
||||||
|
const char *path);
|
||||||
|
|
||||||
int setnonblocking(int fd);
|
int setnonblocking(int fd);
|
||||||
char *gw_strend(register const char *s);
|
char *gw_strend(register const char *s);
|
||||||
static char gw_randomchar();
|
static char gw_randomchar();
|
||||||
|
|||||||
@ -2964,20 +2964,7 @@ int dcb_listen(DCB *listener, const char *config, const char *protocol_name)
|
|||||||
static int dcb_listen_create_socket_inet(const char *host, uint16_t port)
|
static int dcb_listen_create_socket_inet(const char *host, uint16_t port)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage server_address = {};
|
struct sockaddr_storage server_address = {};
|
||||||
int listener_socket = open_network_socket(MXS_SOCKET_LISTENER, &server_address, host, port);
|
return open_network_socket(MXS_SOCKET_LISTENER, &server_address, host, port);
|
||||||
|
|
||||||
if (listener_socket != -1)
|
|
||||||
{
|
|
||||||
if (bind(listener_socket, (struct sockaddr*)&server_address, sizeof(server_address)) < 0)
|
|
||||||
{
|
|
||||||
MXS_ERROR("Failed to bind on '%s:%u': %d, %s",
|
|
||||||
host, port, errno, mxs_strerror(errno));
|
|
||||||
close(listener_socket);
|
|
||||||
listener_socket = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return listener_socket;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2988,59 +2975,16 @@ static int dcb_listen_create_socket_inet(const char *host, uint16_t port)
|
|||||||
*/
|
*/
|
||||||
static int dcb_listen_create_socket_unix(const char *path)
|
static int dcb_listen_create_socket_unix(const char *path)
|
||||||
{
|
{
|
||||||
int listener_socket;
|
if (unlink(path) == -1 && errno != ENOENT)
|
||||||
struct sockaddr_un local_addr;
|
|
||||||
int one = 1;
|
|
||||||
|
|
||||||
if (strlen(path) > sizeof(local_addr.sun_path) - 1)
|
|
||||||
{
|
|
||||||
MXS_ERROR("The path %s specified for the UNIX domain socket is too long. "
|
|
||||||
"The maximum length is %lu.", path, sizeof(local_addr.sun_path) - 1);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// UNIX socket create
|
|
||||||
if ((listener_socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
|
|
||||||
{
|
|
||||||
MXS_ERROR("Can't create UNIX socket: %d, %s", errno, mxs_strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// socket options
|
|
||||||
if (dcb_set_socket_option(listener_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) != 0)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set NONBLOCKING mode
|
|
||||||
if (setnonblocking(listener_socket) != 0)
|
|
||||||
{
|
|
||||||
MXS_ERROR("Failed to set socket to non-blocking mode.");
|
|
||||||
close(listener_socket);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&local_addr, 0, sizeof(local_addr));
|
|
||||||
local_addr.sun_family = AF_UNIX;
|
|
||||||
strcpy(local_addr.sun_path, path);
|
|
||||||
|
|
||||||
if ((-1 == unlink(path)) && (errno != ENOENT))
|
|
||||||
{
|
{
|
||||||
MXS_ERROR("Failed to unlink Unix Socket %s: %d %s",
|
MXS_ERROR("Failed to unlink Unix Socket %s: %d %s",
|
||||||
path, errno, mxs_strerror(errno));
|
path, errno, mxs_strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bind the socket to the Unix domain socket */
|
struct sockaddr_un local_addr;
|
||||||
if (bind(listener_socket, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0)
|
int listener_socket = open_unix_socket(MXS_SOCKET_LISTENER, &local_addr, path);
|
||||||
{
|
|
||||||
MXS_ERROR("Failed to bind to UNIX Domain socket '%s': %d, %s",
|
|
||||||
path, errno, mxs_strerror(errno));
|
|
||||||
close(listener_socket);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set permission for all users */
|
if (listener_socket >= 0 && chmod(path, 0777) < 0)
|
||||||
if (chmod(path, 0777) < 0)
|
|
||||||
{
|
{
|
||||||
MXS_ERROR("Failed to change permissions on UNIX Domain socket '%s': %d, %s",
|
MXS_ERROR("Failed to change permissions on UNIX Domain socket '%s': %d, %s",
|
||||||
path, errno, mxs_strerror(errno));
|
path, errno, mxs_strerror(errno));
|
||||||
|
|||||||
@ -37,6 +37,7 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
@ -974,6 +975,13 @@ int open_network_socket(enum mxs_socket_type type, struct sockaddr_storage *addr
|
|||||||
close(so);
|
close(so);
|
||||||
so = -1;
|
so = -1;
|
||||||
}
|
}
|
||||||
|
else if (type == MXS_SOCKET_LISTENER && bind(so, (struct sockaddr*)addr, sizeof(*addr)) < 0)
|
||||||
|
{
|
||||||
|
MXS_ERROR("Failed to bind on '%s:%u': %d, %s",
|
||||||
|
host, port, errno, mxs_strerror(errno));
|
||||||
|
close(so);
|
||||||
|
so = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
@ -986,6 +994,50 @@ int open_network_socket(enum mxs_socket_type type, struct sockaddr_storage *addr
|
|||||||
return so;
|
return so;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool configure_unix_socket(int so)
|
||||||
|
{
|
||||||
|
int one = 1;
|
||||||
|
|
||||||
|
if (setsockopt(so, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) != 0)
|
||||||
|
{
|
||||||
|
MXS_ERROR("Failed to set socket option: %d, %s.", errno, mxs_strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return setnonblocking(so) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int open_unix_socket(enum mxs_socket_type type, struct sockaddr_un *addr, const char *path)
|
||||||
|
{
|
||||||
|
int fd = -1;
|
||||||
|
|
||||||
|
if (strlen(path) > sizeof(addr->sun_path) - 1)
|
||||||
|
{
|
||||||
|
MXS_ERROR("The path %s specified for the UNIX domain socket is too long. "
|
||||||
|
"The maximum length is %lu.", path, sizeof(addr->sun_path) - 1);
|
||||||
|
}
|
||||||
|
else if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
|
||||||
|
{
|
||||||
|
MXS_ERROR("Can't create UNIX socket: %d, %s", errno, mxs_strerror(errno));
|
||||||
|
}
|
||||||
|
else if (configure_unix_socket(fd))
|
||||||
|
{
|
||||||
|
addr->sun_family = AF_UNIX;
|
||||||
|
strcpy(addr->sun_path, path);
|
||||||
|
|
||||||
|
/* Bind the socket to the Unix domain socket */
|
||||||
|
if (type == MXS_SOCKET_LISTENER && bind(fd, (struct sockaddr *)addr, sizeof(*addr)) < 0)
|
||||||
|
{
|
||||||
|
MXS_ERROR("Failed to bind to UNIX Domain socket '%s': %d, %s",
|
||||||
|
path, errno, mxs_strerror(errno));
|
||||||
|
close(fd);
|
||||||
|
fd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the number of processors available.
|
* Return the number of processors available.
|
||||||
* @return Number of processors or 1 if the required definition of _SC_NPROCESSORS_CONF
|
* @return Number of processors or 1 if the required definition of _SC_NPROCESSORS_CONF
|
||||||
|
|||||||
Reference in New Issue
Block a user