diff --git a/include/maxscale/service.h b/include/maxscale/service.h index b55008b78..c5f090d33 100644 --- a/include/maxscale/service.h +++ b/include/maxscale/service.h @@ -236,6 +236,24 @@ bool serviceAddBackend(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 * diff --git a/server/core/config.cc b/server/core/config.cc index 601dd2966..c50c7f874 100644 --- a/server/core/config.cc +++ b/server/core/config.cc @@ -3456,13 +3456,17 @@ int create_new_listener(CONFIG_CONTEXT *obj) SERVICE *service = service_find(service_name); if (service) { + SERV_LISTENER *listener; SSL_LISTENER *ssl_info = make_ssl_structure(obj, true, &error_count); 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.", - obj->object, service_name, socket); + MXS_ERROR("Creation of listener '%s' for service '%s' failed, because " + "listener '%s' already listens on the socket '%s'.", + obj->object, raw_service_name, listener->name, socket); error_count++; } else @@ -3474,12 +3478,13 @@ int create_new_listener(CONFIG_CONTEXT *obj) 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.", - obj->object, - service_name, - port); + MXS_ERROR("Creation of listener '%s' for service '%s' failed, because " + "listener '%s' already listens on the port %s.", + obj->object, raw_service_name, listener->name, port); error_count++; } else diff --git a/server/core/service.cc b/server/core/service.cc index 531736845..5cf41ea5a 100644 --- a/server/core/service.cc +++ b/server/core/service.cc @@ -806,6 +806,46 @@ SERV_LISTENER* serviceCreateListener(SERVICE *service, const char *name, const c 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 *