Fix listener creation
The correct parameters weren't set in Listener::create and there was no check for two listeners listening on the same socket.
This commit is contained in:
		@ -1141,6 +1141,20 @@ bool runtime_alter_maxscale(const char* name, const char* value)
 | 
				
			|||||||
    return rval;
 | 
					    return rval;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Helper for runtime_create_listener
 | 
				
			||||||
 | 
					inline void set_if_not_null(MXS_CONFIG_PARAMETER& params, const char* name,
 | 
				
			||||||
 | 
					                            const char* value, const char* dflt = nullptr)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if ((!value || strcasecmp(value, CN_DEFAULT) == 0) && dflt)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        params.set(name, dflt);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (value)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        params.set(name, value);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool runtime_create_listener(Service* service,
 | 
					bool runtime_create_listener(Service* service,
 | 
				
			||||||
                             const char* name,
 | 
					                             const char* name,
 | 
				
			||||||
                             const char* addr,
 | 
					                             const char* addr,
 | 
				
			||||||
@ -1163,6 +1177,31 @@ bool runtime_create_listener(Service* service,
 | 
				
			|||||||
    MXS_CONFIG_PARAMETER params;
 | 
					    MXS_CONFIG_PARAMETER params;
 | 
				
			||||||
    bool ok;
 | 
					    bool ok;
 | 
				
			||||||
    tie(ok, params) = load_defaults(proto, MODULE_PROTOCOL, CN_LISTENER);
 | 
					    tie(ok, params) = load_defaults(proto, MODULE_PROTOCOL, CN_LISTENER);
 | 
				
			||||||
 | 
					    params.set(CN_SERVICE, service->name());
 | 
				
			||||||
 | 
					    set_if_not_null(params, CN_AUTHENTICATOR, auth);
 | 
				
			||||||
 | 
					    set_if_not_null(params, CN_AUTHENTICATOR_OPTIONS, auth_opt);
 | 
				
			||||||
 | 
					    bool use_socket = (addr && *addr == '/');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (use_socket)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        params.set(CN_SOCKET, addr);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        set_if_not_null(params, CN_PORT, port, "3306");
 | 
				
			||||||
 | 
					        set_if_not_null(params, CN_ADDRESS, addr, "::");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ssl_key || ssl_cert || ssl_ca)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        params.set(CN_SSL, CN_REQUIRED);
 | 
				
			||||||
 | 
					        set_if_not_null(params, CN_SSL_KEY, ssl_key);
 | 
				
			||||||
 | 
					        set_if_not_null(params, CN_SSL_CERT, ssl_cert);
 | 
				
			||||||
 | 
					        set_if_not_null(params, CN_SSL_CA_CERT, ssl_ca);
 | 
				
			||||||
 | 
					        set_if_not_null(params, CN_SSL_VERSION, ssl_version);
 | 
				
			||||||
 | 
					        set_if_not_null(params, CN_SSL_CERT_VERIFY_DEPTH, ssl_depth);
 | 
				
			||||||
 | 
					        set_if_not_null(params, CN_SSL_VERIFY_PEER_CERTIFICATE, verify_ssl);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsigned short u_port = atoi(port);
 | 
					    unsigned short u_port = atoi(port);
 | 
				
			||||||
    bool rval = false;
 | 
					    bool rval = false;
 | 
				
			||||||
@ -1170,6 +1209,10 @@ bool runtime_create_listener(Service* service,
 | 
				
			|||||||
    std::lock_guard<std::mutex> guard(crt_lock);
 | 
					    std::lock_guard<std::mutex> guard(crt_lock);
 | 
				
			||||||
    std::string reason;
 | 
					    std::string reason;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SListener old_listener = use_socket ?
 | 
				
			||||||
 | 
					        listener_find_by_address(params.get_string(CN_ADDRESS), params.get_integer(CN_PORT)) :
 | 
				
			||||||
 | 
					        listener_find_by_socket(params.get_string(CN_SOCKET));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!ok)
 | 
					    if (!ok)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        config_runtime_error("Failed to load module '%s'", proto);
 | 
					        config_runtime_error("Failed to load module '%s'", proto);
 | 
				
			||||||
@ -1178,33 +1221,13 @@ bool runtime_create_listener(Service* service,
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        config_runtime_error("Listener '%s' already exists", name);
 | 
					        config_runtime_error("Listener '%s' already exists", name);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (SListener l = listener_find_by_address(addr, u_port))
 | 
					    else if (old_listener)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        config_runtime_error("Listener '%s' already listens on [%s]:%u", l->name(), addr, u_port);
 | 
					        config_runtime_error("Listener '%s' already listens on [%s]:%u", old_listener->name(),
 | 
				
			||||||
 | 
					                             old_listener->address(), old_listener->port());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else if (config_is_valid_name(name, &reason))
 | 
					    else if (config_is_valid_name(name, &reason))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (addr == NULL || strcasecmp(addr, CN_DEFAULT) == 0)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            params.set(CN_ADDRESS, "::");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (port == NULL || strcasecmp(port, CN_DEFAULT) == 0)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            params.set(CN_PORT, "3306");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (auth && strcasecmp(auth, CN_DEFAULT) != 0)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            params.set(CN_AUTHENTICATOR, auth);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (auth_opt && strcasecmp(auth_opt, CN_DEFAULT) != 0)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            params.set(CN_AUTHENTICATOR_OPTIONS, auth_opt);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const char* print_addr = addr ? addr : "::";
 | 
					 | 
				
			||||||
        auto listener = Listener::create(name, proto, params);
 | 
					        auto listener = Listener::create(name, proto, params);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (listener && listener_serialize(listener))
 | 
					        if (listener && listener_serialize(listener))
 | 
				
			||||||
@ -1225,8 +1248,8 @@ bool runtime_create_listener(Service* service,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        else
 | 
					        else
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            MXS_ERROR("Failed to create listener '%s' at %s:%s.", name, print_addr, port);
 | 
					            config_runtime_error("Failed to create listener '%s'. Read the MaxScale error log "
 | 
				
			||||||
            config_runtime_error("Failed to create listener '%s' at %s:%s.", name, print_addr, port);
 | 
					                                 "for more details.", name);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
 | 
				
			|||||||
@ -183,10 +183,13 @@ SListener Listener::create(const std::string& name,
 | 
				
			|||||||
    if (strcasecmp(protocol.c_str(), "maxscaled") == 0 && socket_defined
 | 
					    if (strcasecmp(protocol.c_str(), "maxscaled") == 0 && socket_defined
 | 
				
			||||||
        && socket == MAXADMIN_CONFIG_DEFAULT_SOCKET_TAG)
 | 
					        && socket == MAXADMIN_CONFIG_DEFAULT_SOCKET_TAG)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        socket = MAXADMIN_DEFAULT_SOCKET;
 | 
					        socket_defined = true;
 | 
				
			||||||
        address = "";
 | 
					        address = MAXADMIN_DEFAULT_SOCKET;
 | 
				
			||||||
 | 
					        socket = address;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mxb_assert(!address.empty());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (socket_defined)
 | 
					    if (socket_defined)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (auto l = listener_find_by_socket(socket))
 | 
					        if (auto l = listener_find_by_socket(socket))
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user