Move listener parameter handling into Listener::create
The Listener::create method now takes a set of configuration parameters from which it constructs a listener. This removes the duplicated code and makes the behavior of listener creation similar to other objects in MaxScale. It also allows the configuration parameters to be stored in the listener object itself.
This commit is contained in:
@ -52,25 +52,15 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Create a new listener
|
* Create a new listener
|
||||||
*
|
*
|
||||||
* @param service Service where the listener points to
|
* @param name Name of the listener
|
||||||
* @param name Name of the listener
|
* @param protocol Protocol module to use
|
||||||
* @param protocol Protocol module to use
|
* @param params Parameters for the listener
|
||||||
* @param address The address to listen with
|
|
||||||
* @param port The port to listen on
|
|
||||||
* @param authenticator Name of the authenticator to be used
|
|
||||||
* @param auth_options Authenticator options
|
|
||||||
* @param ssl SSL configuration
|
|
||||||
*
|
*
|
||||||
* @return New listener or nullptr on error
|
* @return New listener or nullptr on error
|
||||||
*/
|
*/
|
||||||
static SListener create(SERVICE* service,
|
static SListener create(const std::string& name,
|
||||||
const std::string& name,
|
|
||||||
const std::string& protocol,
|
const std::string& protocol,
|
||||||
const std::string& address,
|
const MXS_CONFIG_PARAMETER& params);
|
||||||
unsigned short port,
|
|
||||||
const std::string& authenticator,
|
|
||||||
const std::string& auth_options,
|
|
||||||
SSL_LISTENER* ssl);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a listener
|
* Destroy a listener
|
||||||
@ -211,20 +201,21 @@ private:
|
|||||||
DESTROYED
|
DESTROYED
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string m_name; /**< Name of the listener */
|
std::string m_name; /**< Name of the listener */
|
||||||
State m_state; /**< Listener state */
|
State m_state; /**< Listener state */
|
||||||
std::string m_protocol; /**< Protocol module to load */
|
std::string m_protocol; /**< Protocol module to load */
|
||||||
uint16_t m_port; /**< Port to listen on */
|
uint16_t m_port; /**< Port to listen on */
|
||||||
std::string m_address; /**< Address to listen with */
|
std::string m_address; /**< Address to listen with */
|
||||||
std::string m_authenticator; /**< Name of authenticator */
|
std::string m_authenticator; /**< Name of authenticator */
|
||||||
std::string m_auth_options; /**< Authenticator options */
|
std::string m_auth_options; /**< Authenticator options */
|
||||||
void* m_auth_instance; /**< Authenticator instance */
|
void* m_auth_instance; /**< Authenticator instance */
|
||||||
SSL_LISTENER* m_ssl; /**< Structure of SSL data or NULL */
|
SSL_LISTENER* m_ssl; /**< Structure of SSL data or NULL */
|
||||||
struct users* m_users; /**< The user data for this listener */
|
struct users* m_users; /**< The user data for this listener */
|
||||||
SERVICE* m_service; /**< The service which used by this listener */
|
SERVICE* m_service; /**< The service which used by this listener */
|
||||||
std::atomic<bool> m_active; /**< True if the port has not been deleted */
|
std::atomic<bool> m_active; /**< True if the port has not been deleted */
|
||||||
MXS_PROTOCOL m_proto_func; /**< Preloaded protocol functions */
|
MXS_PROTOCOL m_proto_func; /**< Preloaded protocol functions */
|
||||||
MXS_AUTHENTICATOR m_auth_func; /**< Preloaded authenticator functions */
|
MXS_AUTHENTICATOR m_auth_func; /**< Preloaded authenticator functions */
|
||||||
|
MXS_CONFIG_PARAMETER m_params; /**< Configuration parameters */
|
||||||
|
|
||||||
Type m_type; /**< The type of the listener */
|
Type m_type; /**< The type of the listener */
|
||||||
|
|
||||||
@ -258,7 +249,8 @@ private:
|
|||||||
*/
|
*/
|
||||||
Listener(SERVICE* service, const std::string& name, const std::string& address, uint16_t port,
|
Listener(SERVICE* service, const std::string& name, const std::string& address, uint16_t port,
|
||||||
const std::string& protocol, const std::string& authenticator,
|
const std::string& protocol, const std::string& authenticator,
|
||||||
const std::string& auth_opts, void* auth_instance, SSL_LISTENER* ssl);
|
const std::string& auth_opts, void* auth_instance, SSL_LISTENER* ssl,
|
||||||
|
const MXS_CONFIG_PARAMETER& params);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listen on a file descriptor shared between all workers
|
* Listen on a file descriptor shared between all workers
|
||||||
|
@ -2887,22 +2887,22 @@ static void free_ssl_structure(SSL_LISTENER* ssl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool config_create_ssl(const char* name,
|
bool config_create_ssl(const char* name,
|
||||||
MXS_CONFIG_PARAMETER* params,
|
const MXS_CONFIG_PARAMETER& params,
|
||||||
bool require_cert,
|
bool require_cert,
|
||||||
SSL_LISTENER** dest)
|
SSL_LISTENER** dest)
|
||||||
{
|
{
|
||||||
SSL_LISTENER* ssl = NULL;
|
SSL_LISTENER* ssl = NULL;
|
||||||
|
|
||||||
// The enum values convert to bool
|
// The enum values convert to bool
|
||||||
int value = params->get_enum(CN_SSL, ssl_values);
|
int value = params.get_enum(CN_SSL, ssl_values);
|
||||||
mxb_assert(value != -1);
|
mxb_assert(value != -1);
|
||||||
|
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
bool error = false;
|
bool error = false;
|
||||||
string ssl_cert = params->get_string(CN_SSL_CERT);
|
string ssl_cert = params.get_string(CN_SSL_CERT);
|
||||||
string ssl_key = params->get_string(CN_SSL_KEY);
|
string ssl_key = params.get_string(CN_SSL_KEY);
|
||||||
string ssl_ca_cert = params->get_string(CN_SSL_CA_CERT);
|
string ssl_ca_cert = params.get_string(CN_SSL_CA_CERT);
|
||||||
|
|
||||||
if (ssl_ca_cert.empty())
|
if (ssl_ca_cert.empty())
|
||||||
{
|
{
|
||||||
@ -2942,12 +2942,12 @@ bool config_create_ssl(const char* name,
|
|||||||
ssl = (SSL_LISTENER*)MXS_CALLOC(1, sizeof(SSL_LISTENER));
|
ssl = (SSL_LISTENER*)MXS_CALLOC(1, sizeof(SSL_LISTENER));
|
||||||
MXS_ABORT_IF_NULL(ssl);
|
MXS_ABORT_IF_NULL(ssl);
|
||||||
|
|
||||||
int ssl_version = params->get_enum(CN_SSL_VERSION, ssl_version_values);
|
int ssl_version = params.get_enum(CN_SSL_VERSION, ssl_version_values);
|
||||||
|
|
||||||
ssl->ssl_method_type = (ssl_method_type_t)ssl_version;
|
ssl->ssl_method_type = (ssl_method_type_t)ssl_version;
|
||||||
ssl->ssl_init_done = false;
|
ssl->ssl_init_done = false;
|
||||||
ssl->ssl_cert_verify_depth = params->get_integer(CN_SSL_CERT_VERIFY_DEPTH);
|
ssl->ssl_cert_verify_depth = params.get_integer(CN_SSL_CERT_VERIFY_DEPTH);
|
||||||
ssl->ssl_verify_peer_certificate = params->get_bool(CN_SSL_VERIFY_PEER_CERTIFICATE);
|
ssl->ssl_verify_peer_certificate = params.get_bool(CN_SSL_VERIFY_PEER_CERTIFICATE);
|
||||||
|
|
||||||
listener_set_certificates(ssl, ssl_cert, ssl_key, ssl_ca_cert);
|
listener_set_certificates(ssl, ssl_cert, ssl_key, ssl_ca_cert);
|
||||||
|
|
||||||
@ -4130,86 +4130,7 @@ int create_new_listener(CONFIG_CONTEXT* obj)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int error_count = 0;
|
return Listener::create(obj->name(), protocol, obj->m_parameters) ? 0 : 1;
|
||||||
|
|
||||||
bool port_defined = obj->m_parameters.contains(CN_PORT);
|
|
||||||
bool socket_defined = obj->m_parameters.contains(CN_SOCKET);
|
|
||||||
|
|
||||||
if (port_defined && socket_defined)
|
|
||||||
{
|
|
||||||
MXS_ERROR("Creation of listener '%s' failed because both 'socket' and 'port' "
|
|
||||||
"are defined. Only one of them is allowed.",
|
|
||||||
obj->name());
|
|
||||||
error_count++;
|
|
||||||
}
|
|
||||||
else if (!port_defined && !socket_defined)
|
|
||||||
{
|
|
||||||
MXS_ERROR("Listener '%s' is missing a required parameter. A Listener "
|
|
||||||
"must have a service, protocol and port (or socket) defined.",
|
|
||||||
obj->name());
|
|
||||||
error_count++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto address = obj->m_parameters.get_string(CN_ADDRESS);
|
|
||||||
Service* service = static_cast<Service*>(obj->m_parameters.get_service(CN_SERVICE));
|
|
||||||
mxb_assert(service);
|
|
||||||
|
|
||||||
// The conditionals just enforce defaults expected in the function.
|
|
||||||
auto port = port_defined ? obj->m_parameters.get_integer(CN_PORT) : 0;
|
|
||||||
auto socket = socket_defined ? obj->m_parameters.get_string(CN_SOCKET) : "";
|
|
||||||
|
|
||||||
// Remove this once maxadmin is removed
|
|
||||||
if (strcasecmp(protocol.c_str(), "maxscaled") == 0 && socket_defined
|
|
||||||
&& socket == MAXADMIN_CONFIG_DEFAULT_SOCKET_TAG)
|
|
||||||
{
|
|
||||||
socket = MAXADMIN_DEFAULT_SOCKET;
|
|
||||||
address = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (socket_defined)
|
|
||||||
{
|
|
||||||
if (auto l = listener_find_by_socket(socket))
|
|
||||||
{
|
|
||||||
MXS_ERROR("Creation of listener '%s' for service '%s' failed, because "
|
|
||||||
"listener '%s' already listens on socket %s.",
|
|
||||||
obj->name(), service->name(), l->name(), socket.c_str());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (auto l = listener_find_by_address(address, port))
|
|
||||||
{
|
|
||||||
MXS_ERROR("Creation of listener '%s' for service '%s' failed, because "
|
|
||||||
"listener '%s' already listens on port %s.",
|
|
||||||
obj->name(), service->name(), l->name(),
|
|
||||||
obj->m_parameters.get_string(CN_PORT).c_str());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto protocol = obj->m_parameters.get_string(CN_PROTOCOL);
|
|
||||||
SSL_LISTENER* ssl_info = NULL;
|
|
||||||
|
|
||||||
if (!config_create_ssl(obj->name(), &obj->m_parameters, true, &ssl_info))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// These two values being NULL trigger the loading of the default
|
|
||||||
// authenticators that are specific to each protocol module
|
|
||||||
auto authenticator = obj->m_parameters.get_string(CN_AUTHENTICATOR);
|
|
||||||
auto authenticator_options = obj->m_parameters.get_string(CN_AUTHENTICATOR_OPTIONS);
|
|
||||||
int net_port = socket_defined ? 0 : port;
|
|
||||||
|
|
||||||
auto listener = Listener::create(service, obj->name(), protocol, socket_defined ? socket : address,
|
|
||||||
net_port, authenticator, authenticator_options, ssl_info);
|
|
||||||
|
|
||||||
if (!listener)
|
|
||||||
{
|
|
||||||
++error_count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return error_count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -470,7 +470,7 @@ static SSL_LISTENER* create_ssl(const char* name,
|
|||||||
&& (!depth || config_add_param(obj, CN_SSL_CERT_VERIFY_DEPTH, depth))
|
&& (!depth || config_add_param(obj, CN_SSL_CERT_VERIFY_DEPTH, depth))
|
||||||
&& (!verify || config_add_param(obj, CN_SSL_VERIFY_PEER_CERTIFICATE, verify)))
|
&& (!verify || config_add_param(obj, CN_SSL_VERIFY_PEER_CERTIFICATE, verify)))
|
||||||
{
|
{
|
||||||
config_create_ssl(name, &obj->m_parameters, true, &rval);
|
config_create_ssl(name, obj->m_parameters, true, &rval);
|
||||||
}
|
}
|
||||||
|
|
||||||
config_context_free(obj);
|
config_context_free(obj);
|
||||||
@ -1155,31 +1155,14 @@ bool runtime_create_listener(Service* service,
|
|||||||
const char* ssl_depth,
|
const char* ssl_depth,
|
||||||
const char* verify_ssl)
|
const char* verify_ssl)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (addr == NULL || strcasecmp(addr, CN_DEFAULT) == 0)
|
|
||||||
{
|
|
||||||
addr = "::";
|
|
||||||
}
|
|
||||||
if (port == NULL || strcasecmp(port, CN_DEFAULT) == 0)
|
|
||||||
{
|
|
||||||
port = "3306";
|
|
||||||
}
|
|
||||||
if (proto == NULL || strcasecmp(proto, CN_DEFAULT) == 0)
|
if (proto == NULL || strcasecmp(proto, CN_DEFAULT) == 0)
|
||||||
{
|
{
|
||||||
proto = "mariadbclient";
|
proto = "mariadbclient";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!auth || strcasecmp(auth, CN_DEFAULT) == 0)
|
MXS_CONFIG_PARAMETER params;
|
||||||
{
|
bool ok;
|
||||||
/** Use protocol default authenticator*/
|
tie(ok, params) = load_defaults(proto, MODULE_PROTOCOL, CN_LISTENER);
|
||||||
auth = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!auth_opt || strcasecmp(auth_opt, CN_DEFAULT) == 0)
|
|
||||||
{
|
|
||||||
/** Don't pass options to the authenticator */
|
|
||||||
auth_opt = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned short u_port = atoi(port);
|
unsigned short u_port = atoi(port);
|
||||||
bool rval = false;
|
bool rval = false;
|
||||||
@ -1187,7 +1170,11 @@ 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;
|
||||||
|
|
||||||
if (listener_find(name))
|
if (!ok)
|
||||||
|
{
|
||||||
|
config_runtime_error("Failed to load module '%s'", proto);
|
||||||
|
}
|
||||||
|
else if (listener_find(name))
|
||||||
{
|
{
|
||||||
config_runtime_error("Listener '%s' already exists", name);
|
config_runtime_error("Listener '%s' already exists", name);
|
||||||
}
|
}
|
||||||
@ -1197,49 +1184,50 @@ bool runtime_create_listener(Service* service,
|
|||||||
}
|
}
|
||||||
else if (config_is_valid_name(name, &reason))
|
else if (config_is_valid_name(name, &reason))
|
||||||
{
|
{
|
||||||
SSL_LISTENER* ssl = NULL;
|
if (addr == NULL || strcasecmp(addr, CN_DEFAULT) == 0)
|
||||||
|
|
||||||
if (ssl_key && ssl_cert && ssl_ca
|
|
||||||
&& (ssl =
|
|
||||||
create_ssl(name,
|
|
||||||
ssl_key,
|
|
||||||
ssl_cert,
|
|
||||||
ssl_ca,
|
|
||||||
ssl_version,
|
|
||||||
ssl_depth,
|
|
||||||
verify_ssl)) == NULL)
|
|
||||||
{
|
{
|
||||||
MXS_ERROR("SSL initialization for listener '%s' failed.", name);
|
params.set(CN_ADDRESS, "::");
|
||||||
config_runtime_error("SSL initialization for listener '%s' failed.", name);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (port == NULL || strcasecmp(port, CN_DEFAULT) == 0)
|
||||||
{
|
{
|
||||||
const char* print_addr = addr ? addr : "::";
|
params.set(CN_PORT, "3306");
|
||||||
auto listener = Listener::create(service, name, proto, addr, u_port, auth, auth_opt, ssl);
|
}
|
||||||
|
|
||||||
if (listener && listener_serialize(listener))
|
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);
|
||||||
|
|
||||||
|
if (listener && listener_serialize(listener))
|
||||||
|
{
|
||||||
|
if (listener->listen())
|
||||||
{
|
{
|
||||||
MXS_NOTICE("Created %slistener '%s' at %s:%s for service '%s'",
|
MXS_NOTICE("Created listener '%s' at %s:%u for service '%s'",
|
||||||
ssl ? "TLS encrypted " : "", name, print_addr, port, service->name());
|
name, listener->address(), listener->port(), service->name());
|
||||||
|
|
||||||
if (listener->listen())
|
rval = true;
|
||||||
{
|
|
||||||
rval = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MXS_ERROR("Listener '%s' was created but failed to start it.", name);
|
|
||||||
config_runtime_error("Listener '%s' was created but failed to start it.", name);
|
|
||||||
Listener::destroy(listener);
|
|
||||||
mxb_assert(!listener_find(name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MXS_ERROR("Failed to create listener '%s' at %s:%s.", name, print_addr, port);
|
config_runtime_error("Listener '%s' was created but failed to start it.", name);
|
||||||
config_runtime_error("Failed to create listener '%s' at %s:%s.", name, print_addr, port);
|
Listener::destroy(listener);
|
||||||
|
mxb_assert(!listener_find(name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MXS_ERROR("Failed to create listener '%s' at %s:%s.", name, print_addr, port);
|
||||||
|
config_runtime_error("Failed to create listener '%s' at %s:%s.", name, print_addr, port);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -70,9 +70,9 @@ void config_set_global_defaults();
|
|||||||
*/
|
*/
|
||||||
void config_add_defaults(CONFIG_CONTEXT* ctx, const MXS_MODULE_PARAM* params);
|
void config_add_defaults(CONFIG_CONTEXT* ctx, const MXS_MODULE_PARAM* params);
|
||||||
|
|
||||||
char* config_clean_string_list(const char* str);
|
char* config_clean_string_list(const char* str);
|
||||||
bool config_load(const char*);
|
bool config_load(const char*);
|
||||||
bool config_load_global(const char* filename);
|
bool config_load_global(const char* filename);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates an empty configuration context
|
* @brief Creates an empty configuration context
|
||||||
@ -140,7 +140,7 @@ void config_remove_param(CONFIG_CONTEXT* obj, const char* name);
|
|||||||
* @return True on success, false on error
|
* @return True on success, false on error
|
||||||
*/
|
*/
|
||||||
bool config_create_ssl(const char* name,
|
bool config_create_ssl(const char* name,
|
||||||
MXS_CONFIG_PARAMETER* params,
|
const MXS_CONFIG_PARAMETER& params,
|
||||||
bool require_cert,
|
bool require_cert,
|
||||||
SSL_LISTENER** dest);
|
SSL_LISTENER** dest);
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
|
#include <maxscale/maxadmin.h>
|
||||||
#include <maxscale/paths.h>
|
#include <maxscale/paths.h>
|
||||||
#include <maxscale/ssl.hh>
|
#include <maxscale/ssl.hh>
|
||||||
#include <maxscale/protocol.hh>
|
#include <maxscale/protocol.hh>
|
||||||
@ -40,6 +41,7 @@
|
|||||||
|
|
||||||
#include "internal/modules.hh"
|
#include "internal/modules.hh"
|
||||||
#include "internal/session.hh"
|
#include "internal/session.hh"
|
||||||
|
#include "internal/config.hh"
|
||||||
|
|
||||||
using Clock = std::chrono::steady_clock;
|
using Clock = std::chrono::steady_clock;
|
||||||
using std::chrono::seconds;
|
using std::chrono::seconds;
|
||||||
@ -99,9 +101,16 @@ private:
|
|||||||
thread_local RateLimit rate_limit;
|
thread_local RateLimit rate_limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
Listener::Listener(SERVICE* service, const std::string& name, const std::string& address,
|
Listener::Listener(SERVICE* service,
|
||||||
uint16_t port, const std::string& protocol, const std::string& authenticator,
|
const std::string& name,
|
||||||
const std::string& auth_opts, void* auth_instance, SSL_LISTENER* ssl)
|
const std::string& address,
|
||||||
|
uint16_t port,
|
||||||
|
const std::string& protocol,
|
||||||
|
const std::string& authenticator,
|
||||||
|
const std::string& auth_opts,
|
||||||
|
void* auth_instance,
|
||||||
|
SSL_LISTENER* ssl,
|
||||||
|
const MXS_CONFIG_PARAMETER& params)
|
||||||
: MXB_POLL_DATA{Listener::poll_handler}
|
: MXB_POLL_DATA{Listener::poll_handler}
|
||||||
, m_name(name)
|
, m_name(name)
|
||||||
, m_state(CREATED)
|
, m_state(CREATED)
|
||||||
@ -116,6 +125,7 @@ Listener::Listener(SERVICE* service, const std::string& name, const std::string&
|
|||||||
, m_service(service)
|
, m_service(service)
|
||||||
, m_proto_func(*(MXS_PROTOCOL*)load_module(protocol.c_str(), MODULE_PROTOCOL))
|
, m_proto_func(*(MXS_PROTOCOL*)load_module(protocol.c_str(), MODULE_PROTOCOL))
|
||||||
, m_auth_func(*(MXS_AUTHENTICATOR*)load_module(authenticator.c_str(), MODULE_AUTHENTICATOR))
|
, m_auth_func(*(MXS_AUTHENTICATOR*)load_module(authenticator.c_str(), MODULE_AUTHENTICATOR))
|
||||||
|
, m_params(params)
|
||||||
{
|
{
|
||||||
if (strcasecmp(service->router_name(), "cli") == 0 || strcasecmp(service->router_name(), "maxinfo") == 0)
|
if (strcasecmp(service->router_name(), "cli") == 0 || strcasecmp(service->router_name(), "maxinfo") == 0)
|
||||||
{
|
{
|
||||||
@ -145,15 +155,75 @@ Listener::~Listener()
|
|||||||
SSL_LISTENER_free(m_ssl);
|
SSL_LISTENER_free(m_ssl);
|
||||||
}
|
}
|
||||||
|
|
||||||
SListener Listener::create(SERVICE* service,
|
SListener Listener::create(const std::string& name,
|
||||||
const std::string& name,
|
|
||||||
const std::string& protocol,
|
const std::string& protocol,
|
||||||
const std::string& address,
|
const MXS_CONFIG_PARAMETER& params)
|
||||||
unsigned short port,
|
|
||||||
const std::string& authenticator,
|
|
||||||
const std::string& auth_options,
|
|
||||||
SSL_LISTENER* ssl)
|
|
||||||
{
|
{
|
||||||
|
bool port_defined = params.contains(CN_PORT);
|
||||||
|
bool socket_defined = params.contains(CN_SOCKET);
|
||||||
|
Service* service = static_cast<Service*>(params.get_service(CN_SERVICE));
|
||||||
|
|
||||||
|
if (port_defined && socket_defined)
|
||||||
|
{
|
||||||
|
MXS_ERROR("Creation of listener '%s' failed because both 'socket' and 'port' "
|
||||||
|
"are defined. Only one of them is allowed.",
|
||||||
|
name.c_str());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
else if ((!port_defined && !socket_defined) || !service)
|
||||||
|
{
|
||||||
|
MXS_ERROR("Listener '%s' is missing a required parameter. A Listener "
|
||||||
|
"must have a service, protocol and port (or socket) defined.",
|
||||||
|
name.c_str());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The conditionals just enforce defaults expected in the function.
|
||||||
|
auto port = port_defined ? params.get_integer(CN_PORT) : 0;
|
||||||
|
auto socket = socket_defined ? params.get_string(CN_SOCKET) : "";
|
||||||
|
auto address = socket_defined ? params.get_string(CN_SOCKET) : params.get_string(CN_ADDRESS);
|
||||||
|
|
||||||
|
// Remove this once maxadmin is removed
|
||||||
|
if (strcasecmp(protocol.c_str(), "maxscaled") == 0 && socket_defined
|
||||||
|
&& socket == MAXADMIN_CONFIG_DEFAULT_SOCKET_TAG)
|
||||||
|
{
|
||||||
|
socket = MAXADMIN_DEFAULT_SOCKET;
|
||||||
|
address = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (socket_defined)
|
||||||
|
{
|
||||||
|
if (auto l = listener_find_by_socket(socket))
|
||||||
|
{
|
||||||
|
MXS_ERROR("Creation of listener '%s' for service '%s' failed, because "
|
||||||
|
"listener '%s' already listens on socket %s.",
|
||||||
|
name.c_str(), service->name(), l->name(), socket.c_str());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (auto l = listener_find_by_address(address, port))
|
||||||
|
{
|
||||||
|
MXS_ERROR("Creation of listener '%s' for service '%s' failed, because "
|
||||||
|
"listener '%s' already listens on port %s.",
|
||||||
|
name.c_str(), service->name(), l->name(),
|
||||||
|
params.get_string(CN_PORT).c_str());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
SSL_LISTENER* ssl_info = NULL;
|
||||||
|
|
||||||
|
if (!config_create_ssl(name.c_str(), params, true, &ssl_info))
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// These two values being NULL trigger the loading of the default
|
||||||
|
// authenticators that are specific to each protocol module
|
||||||
|
auto authenticator = params.get_string(CN_AUTHENTICATOR);
|
||||||
|
auto authenticator_options = params.get_string(CN_AUTHENTICATOR_OPTIONS);
|
||||||
|
int net_port = socket_defined ? 0 : port;
|
||||||
|
|
||||||
|
|
||||||
const char* auth = !authenticator.empty() ? authenticator.c_str() :
|
const char* auth = !authenticator.empty() ? authenticator.c_str() :
|
||||||
get_default_authenticator(protocol.c_str());
|
get_default_authenticator(protocol.c_str());
|
||||||
|
|
||||||
@ -166,7 +236,7 @@ SListener Listener::create(SERVICE* service,
|
|||||||
|
|
||||||
void* auth_instance = NULL;
|
void* auth_instance = NULL;
|
||||||
|
|
||||||
if (!authenticator_init(&auth_instance, auth, auth_options.c_str()))
|
if (!authenticator_init(&auth_instance, auth, authenticator_options.c_str()))
|
||||||
{
|
{
|
||||||
MXS_ERROR("Failed to initialize authenticator module '%s' for listener '%s'.",
|
MXS_ERROR("Failed to initialize authenticator module '%s' for listener '%s'.",
|
||||||
auth, name.c_str());
|
auth, name.c_str());
|
||||||
@ -179,7 +249,7 @@ SListener Listener::create(SERVICE* service,
|
|||||||
mxb_assert(proto_mod && auth_mod);
|
mxb_assert(proto_mod && auth_mod);
|
||||||
|
|
||||||
SListener listener(new(std::nothrow) Listener(service, name, address, port, protocol, auth,
|
SListener listener(new(std::nothrow) Listener(service, name, address, port, protocol, auth,
|
||||||
auth_options, auth_instance, ssl));
|
authenticator_options, auth_instance, ssl_info, params));
|
||||||
|
|
||||||
if (listener)
|
if (listener)
|
||||||
{
|
{
|
||||||
|
@ -197,7 +197,7 @@ Server* Server::server_alloc(const char* name, MXS_CONFIG_PARAMETER* params)
|
|||||||
|
|
||||||
SSL_LISTENER* ssl = NULL;
|
SSL_LISTENER* ssl = NULL;
|
||||||
|
|
||||||
if (!config_create_ssl(name, params, false, &ssl))
|
if (!config_create_ssl(name, *params, false, &ssl))
|
||||||
{
|
{
|
||||||
MXS_ERROR("Unable to initialize SSL for server '%s'", name);
|
MXS_ERROR("Unable to initialize SSL for server '%s'", name);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -54,7 +54,15 @@ static int test1()
|
|||||||
parameters.set("max_retry_interval", "10s");
|
parameters.set("max_retry_interval", "10s");
|
||||||
parameters.set("connection_timeout", "10s");
|
parameters.set("connection_timeout", "10s");
|
||||||
auto service = service_alloc("service", "readconnroute", ¶meters);
|
auto service = service_alloc("service", "readconnroute", ¶meters);
|
||||||
auto listener = Listener::create(service, "listener", "mariadbclient", "0.0.0.0", 3306, "", "", nullptr);
|
|
||||||
|
MXS_CONFIG_PARAMETER listener_params;
|
||||||
|
listener_params.set(CN_ADDRESS, "0.0.0.0");
|
||||||
|
listener_params.set(CN_PORT, "3306");
|
||||||
|
listener_params.set(CN_PROTOCOL, "mariadbclient");
|
||||||
|
listener_params.set(CN_SERVICE, service->name());
|
||||||
|
|
||||||
|
auto listener = Listener::create("listener", "mariadbclient", listener_params);
|
||||||
|
|
||||||
auto session = new mxs::Session(listener);
|
auto session = new mxs::Session(listener);
|
||||||
dcb = dcb_alloc(DCB::Role::INTERNAL, session);
|
dcb = dcb_alloc(DCB::Role::INTERNAL, session);
|
||||||
printDCB(dcb);
|
printDCB(dcb);
|
||||||
|
@ -60,7 +60,15 @@ static int test1()
|
|||||||
parameters.set(CN_MAX_RETRY_INTERVAL, "10s");
|
parameters.set(CN_MAX_RETRY_INTERVAL, "10s");
|
||||||
parameters.set(CN_CONNECTION_TIMEOUT, "10s");
|
parameters.set(CN_CONNECTION_TIMEOUT, "10s");
|
||||||
auto service = service_alloc("service", "readconnroute", ¶meters);
|
auto service = service_alloc("service", "readconnroute", ¶meters);
|
||||||
auto listener = Listener::create(service, "listener", "mariadbclient", "0.0.0.0", 3306, "", "", nullptr);
|
|
||||||
|
MXS_CONFIG_PARAMETER listener_params;
|
||||||
|
listener_params.set(CN_ADDRESS, "0.0.0.0");
|
||||||
|
listener_params.set(CN_PORT, "3306");
|
||||||
|
listener_params.set(CN_PROTOCOL, "mariadbclient");
|
||||||
|
listener_params.set(CN_SERVICE, service->name());
|
||||||
|
|
||||||
|
auto listener = Listener::create("listener", "mariadbclient", listener_params);
|
||||||
|
|
||||||
auto session = new mxs::Session(listener);
|
auto session = new mxs::Session(listener);
|
||||||
dcb = dcb_alloc(DCB::Role::CLIENT, session);
|
dcb = dcb_alloc(DCB::Role::CLIENT, session);
|
||||||
|
|
||||||
|
@ -78,14 +78,14 @@ static int test1()
|
|||||||
mxb_assert_message(0 != service_isvalid(service), "Service must be valid after creation");
|
mxb_assert_message(0 != service_isvalid(service), "Service must be valid after creation");
|
||||||
mxb_assert_message(0 == strcmp("MyService", service->name()), "Service must have given name");
|
mxb_assert_message(0 == strcmp("MyService", service->name()), "Service must have given name");
|
||||||
fprintf(stderr, "\t..done\nAdding protocol testprotocol.");
|
fprintf(stderr, "\t..done\nAdding protocol testprotocol.");
|
||||||
mxb_assert_message(Listener::create(service,
|
|
||||||
"TestProtocol",
|
MXS_CONFIG_PARAMETER listener_params;
|
||||||
"mariadbclient",
|
listener_params.set(CN_ADDRESS, "localhost");
|
||||||
"localhost",
|
listener_params.set(CN_PORT, "9876");
|
||||||
9876,
|
listener_params.set(CN_PROTOCOL, "mariadbclient");
|
||||||
"MySQLAuth",
|
listener_params.set(CN_SERVICE, service->name());
|
||||||
"",
|
|
||||||
NULL),
|
mxb_assert_message(Listener::create("TestProtocol", "mariadbclient", listener_params),
|
||||||
"Add Protocol should succeed");
|
"Add Protocol should succeed");
|
||||||
mxb_assert_message(service_find_listener(service, "", "localhost", 9876),
|
mxb_assert_message(service_find_listener(service, "", "localhost", 9876),
|
||||||
"Service should have new protocol as requested");
|
"Service should have new protocol as requested");
|
||||||
|
@ -141,7 +141,7 @@ string create_unique_select()
|
|||||||
|
|
||||||
int test(mock::Session& session,
|
int test(mock::Session& session,
|
||||||
FilterModule::Session& filter_session,
|
FilterModule::Session& filter_session,
|
||||||
mock::RouterSession& router_session,
|
mock::RouterSession& router_session,
|
||||||
const TEST_CASE& tc)
|
const TEST_CASE& tc)
|
||||||
{
|
{
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
@ -293,7 +293,15 @@ int test(FilterModule::Instance& filter_instance, const TEST_CASE& tc)
|
|||||||
parameters.set("connection_timeout", "10s");
|
parameters.set("connection_timeout", "10s");
|
||||||
|
|
||||||
auto service = service_alloc("service", "readconnroute", ¶meters);
|
auto service = service_alloc("service", "readconnroute", ¶meters);
|
||||||
auto listener = Listener::create(service, "listener", "mariadbclient", "0.0.0.0", 3306, "", "", nullptr);
|
|
||||||
|
MXS_CONFIG_PARAMETER listener_params;
|
||||||
|
listener_params.set(CN_ADDRESS, "0.0.0.0");
|
||||||
|
listener_params.set(CN_PORT, "3306");
|
||||||
|
listener_params.set(CN_PROTOCOL, "mariadbclient");
|
||||||
|
listener_params.set(CN_SERVICE, service->name());
|
||||||
|
|
||||||
|
auto listener = Listener::create("listener", "mariadbclient", listener_params);
|
||||||
|
|
||||||
mock::Client client("bob", "127.0.0.1");
|
mock::Client client("bob", "127.0.0.1");
|
||||||
mock::Session session(&client, listener);
|
mock::Session session(&client, listener);
|
||||||
mock::ResultSetBackend backend;
|
mock::ResultSetBackend backend;
|
||||||
|
@ -708,7 +708,7 @@ void log_error(const FW_TEST_CASE& c)
|
|||||||
|
|
||||||
int test(mock::Client& client,
|
int test(mock::Client& client,
|
||||||
FilterModule::Session& filter_session,
|
FilterModule::Session& filter_session,
|
||||||
mock::RouterSession& router_session,
|
mock::RouterSession& router_session,
|
||||||
const FW_TEST_CASE& c)
|
const FW_TEST_CASE& c)
|
||||||
{
|
{
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
@ -772,8 +772,15 @@ int test(FilterModule::Instance& filter_instance, const FW_TEST& t)
|
|||||||
parameters.set("max_retry_interval", "10s");
|
parameters.set("max_retry_interval", "10s");
|
||||||
parameters.set("connection_timeout", "10s");
|
parameters.set("connection_timeout", "10s");
|
||||||
auto service = service_alloc("service", "readconnroute", ¶meters);
|
auto service = service_alloc("service", "readconnroute", ¶meters);
|
||||||
auto listener = Listener::create(service, "listener", "mariadbclient", "0.0.0.0", 3306,
|
|
||||||
"", "", nullptr);
|
MXS_CONFIG_PARAMETER listener_params;
|
||||||
|
listener_params.set(CN_ADDRESS, "0.0.0.0");
|
||||||
|
listener_params.set(CN_PORT, "3306");
|
||||||
|
listener_params.set(CN_PROTOCOL, "mariadbclient");
|
||||||
|
listener_params.set(CN_SERVICE, service->name());
|
||||||
|
|
||||||
|
auto listener = Listener::create("listener", "mariadbclient", listener_params);
|
||||||
|
|
||||||
mock::Session session(&client, listener);
|
mock::Session session(&client, listener);
|
||||||
mock::OkBackend backend;
|
mock::OkBackend backend;
|
||||||
mock::RouterSession router_session(&backend, &session);
|
mock::RouterSession router_session(&backend, &session);
|
||||||
|
@ -188,8 +188,13 @@ static void blr_start_master(void* data)
|
|||||||
pthread_mutex_unlock(&router->lock);
|
pthread_mutex_unlock(&router->lock);
|
||||||
|
|
||||||
// Create a temporary listener so we can create a session originating from it
|
// Create a temporary listener so we can create a session originating from it
|
||||||
auto listener = Listener::create(router->service, "binlogrouter_listener", "mariadbclient",
|
MXS_CONFIG_PARAMETER listener_params;
|
||||||
"127.0.0.1", 9999, "", "", nullptr);
|
listener_params.set(CN_ADDRESS, "127.0.0.1");
|
||||||
|
listener_params.set(CN_PORT, "9999");
|
||||||
|
listener_params.set(CN_PROTOCOL, "mariadbclient");
|
||||||
|
listener_params.set(CN_SERVICE, router->service->name());
|
||||||
|
|
||||||
|
auto listener = Listener::create("binlogrouter_listener", "mariadbclient", listener_params);
|
||||||
mxb_assert(listener);
|
mxb_assert(listener);
|
||||||
|
|
||||||
// Load users now so that authentication will work for the fake client
|
// Load users now so that authentication will work for the fake client
|
||||||
@ -1708,7 +1713,7 @@ bool blr_send_event(blr_thread_role_t role,
|
|||||||
const char* binlog_name,
|
const char* binlog_name,
|
||||||
uint32_t binlog_pos,
|
uint32_t binlog_pos,
|
||||||
ROUTER_SLAVE* slave,
|
ROUTER_SLAVE* slave,
|
||||||
REP_HEADER* hdr,
|
REP_HEADER* hdr,
|
||||||
uint8_t* buf)
|
uint8_t* buf)
|
||||||
{
|
{
|
||||||
bool rval = true;
|
bool rval = true;
|
||||||
|
Reference in New Issue
Block a user