MXS-1689 Properly check for duplicate port/socket of service

It is now impossible to create two listeners for a service that
would listen on the same port/socket (as before), but the error
message is now sensible and provides detailed information to the
user.
This commit is contained in:
Johan Wikman
2018-03-07 13:02:12 +02:00
parent ff9024bdfb
commit 7ae3931511
3 changed files with 71 additions and 8 deletions

View File

@ -236,6 +236,24 @@ bool serviceAddBackend(SERVICE *service, SERVER *server);
*/ */
bool serviceHasBackend(SERVICE *service, SERVER *server); bool serviceHasBackend(SERVICE *service, SERVER *server);
/**
* @brief Find listener with specified properties.
*
* @param service Service to check
* @param socket Listener socket path
* @param address Listener address
* @param port Listener port number
*
* @note Either socket should be NULL and port non-zero or socket
* non-NULL and port zero.
*
* @return True if service has the listener
*/
SERV_LISTENER* service_find_listener(SERVICE* service,
const char* socket,
const char* address,
unsigned short port);
/** /**
* @brief Check if a service has a listener * @brief Check if a service has a listener
* *

View File

@ -3456,13 +3456,17 @@ int create_new_listener(CONFIG_CONTEXT *obj)
SERVICE *service = service_find(service_name); SERVICE *service = service_find(service_name);
if (service) if (service)
{ {
SERV_LISTENER *listener;
SSL_LISTENER *ssl_info = make_ssl_structure(obj, true, &error_count); SSL_LISTENER *ssl_info = make_ssl_structure(obj, true, &error_count);
if (socket) if (socket)
{ {
if (serviceHasListener(service, obj->object, protocol, address, 0)) listener = service_find_listener(service, socket, NULL, 0);
if (listener)
{ {
MXS_ERROR("Listener '%s' for service '%s' already has a socket at '%s.", MXS_ERROR("Creation of listener '%s' for service '%s' failed, because "
obj->object, service_name, socket); "listener '%s' already listens on the socket '%s'.",
obj->object, raw_service_name, listener->name, socket);
error_count++; error_count++;
} }
else else
@ -3474,12 +3478,13 @@ int create_new_listener(CONFIG_CONTEXT *obj)
if (port) if (port)
{ {
if (serviceHasListener(service, obj->object, protocol, address, atoi(port))) listener = service_find_listener(service, NULL, address, atoi(port));
if (listener)
{ {
MXS_ERROR("Listener '%s', for service '%s', already have port %s.", MXS_ERROR("Creation of listener '%s' for service '%s' failed, because "
obj->object, "listener '%s' already listens on the port %s.",
service_name, obj->object, raw_service_name, listener->name, port);
port);
error_count++; error_count++;
} }
else else

View File

@ -806,6 +806,46 @@ SERV_LISTENER* serviceCreateListener(SERVICE *service, const char *name, const c
return proto; return proto;
} }
SERV_LISTENER* service_find_listener(SERVICE* service,
const char* socket,
const char* address, unsigned short port)
{
LISTENER_ITERATOR iter;
for (SERV_LISTENER *listener = listener_iterator_init(service, &iter);
listener; listener = listener_iterator_next(&iter))
{
if (listener_is_active(listener))
{
bool is_same_port = false;
if (port && (port == listener->port) &&
((address && listener->address && strcmp(listener->address, address) == 0) ||
(address == NULL && listener->address == NULL)))
{
is_same_port = true;
}
bool is_same_socket = false;
if (!is_same_port)
{
if (socket && listener->address && strcmp(listener->address, socket) == 0)
{
is_same_socket = true;
}
}
if (is_same_port || is_same_socket)
{
return listener;
}
}
}
return NULL;
}
/** /**
* Check if a protocol/port pair is part of the service * Check if a protocol/port pair is part of the service
* *