MXS-2197: Make SERV_LISTENER a C++ class
The class is still mostly the same as the old C version but it now uses std::string instead of char pointers. Changed configuration default values so that the parameters passed to the listener allocation are always valid.
This commit is contained in:
@ -23,6 +23,8 @@
|
|||||||
#include <maxbase/jansson.h>
|
#include <maxbase/jansson.h>
|
||||||
#include <maxscale/buffer.h>
|
#include <maxscale/buffer.h>
|
||||||
|
|
||||||
|
class SERV_LISTENER;
|
||||||
|
|
||||||
MXS_BEGIN_DECLS
|
MXS_BEGIN_DECLS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,7 +46,6 @@ typedef enum authenticator_capability
|
|||||||
struct dcb;
|
struct dcb;
|
||||||
struct server;
|
struct server;
|
||||||
struct session;
|
struct session;
|
||||||
struct servlistener;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @verbatim
|
* @verbatim
|
||||||
@ -96,8 +97,8 @@ typedef struct mxs_authenticator
|
|||||||
int (* authenticate)(struct dcb*);
|
int (* authenticate)(struct dcb*);
|
||||||
void (* free)(struct dcb*);
|
void (* free)(struct dcb*);
|
||||||
void (* destroy)(void*);
|
void (* destroy)(void*);
|
||||||
int (* loadusers)(struct servlistener*);
|
int (* loadusers)(SERV_LISTENER*);
|
||||||
void (* diagnostic)(struct dcb*, struct servlistener*);
|
void (* diagnostic)(struct dcb*, SERV_LISTENER*);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return diagnostic information about the authenticator
|
* @brief Return diagnostic information about the authenticator
|
||||||
@ -111,7 +112,7 @@ typedef struct mxs_authenticator
|
|||||||
*
|
*
|
||||||
* @see jansson.h
|
* @see jansson.h
|
||||||
*/
|
*/
|
||||||
json_t* (*diagnostic_json)(const struct servlistener* listener);
|
json_t* (*diagnostic_json)(const SERV_LISTENER * listener);
|
||||||
|
|
||||||
/** This entry point was added to avoid calling authenticator functions
|
/** This entry point was added to avoid calling authenticator functions
|
||||||
* directly when a COM_CHANGE_USER command is executed. */
|
* directly when a COM_CHANGE_USER command is executed. */
|
||||||
|
@ -26,14 +26,15 @@
|
|||||||
#include <maxscale/protocol.h>
|
#include <maxscale/protocol.h>
|
||||||
#include <maxscale/ssl.h>
|
#include <maxscale/ssl.h>
|
||||||
|
|
||||||
|
class SERVICE;
|
||||||
|
class SERV_LISTENER;
|
||||||
|
|
||||||
MXS_BEGIN_DECLS
|
MXS_BEGIN_DECLS
|
||||||
|
|
||||||
#define ERRHANDLE
|
#define ERRHANDLE
|
||||||
|
|
||||||
struct session;
|
struct session;
|
||||||
struct server;
|
struct server;
|
||||||
struct service;
|
|
||||||
struct servlistener;
|
|
||||||
|
|
||||||
struct dcb;
|
struct dcb;
|
||||||
|
|
||||||
@ -188,7 +189,7 @@ typedef struct dcb
|
|||||||
size_t protocol_packet_length; /**< How long the protocol specific packet is */
|
size_t protocol_packet_length; /**< How long the protocol specific packet is */
|
||||||
size_t protocol_bytes_processed; /**< How many bytes of a packet have been read */
|
size_t protocol_bytes_processed; /**< How many bytes of a packet have been read */
|
||||||
struct session* session; /**< The owning session */
|
struct session* session; /**< The owning session */
|
||||||
struct servlistener* listener; /**< For a client DCB, the listener data */
|
SERV_LISTENER* listener; /**< For a client DCB, the listener data */
|
||||||
MXS_PROTOCOL func; /**< The protocol functions for this descriptor */
|
MXS_PROTOCOL func; /**< The protocol functions for this descriptor */
|
||||||
MXS_AUTHENTICATOR authfunc; /**< The authenticator functions for this descriptor
|
MXS_AUTHENTICATOR authfunc; /**< The authenticator functions for this descriptor
|
||||||
* */
|
* */
|
||||||
@ -207,7 +208,7 @@ typedef struct dcb
|
|||||||
* -1: Evicted from the persistent pool and being closed.
|
* -1: Evicted from the persistent pool and being closed.
|
||||||
* non-0: Time when placed in the persistent pool.
|
* non-0: Time when placed in the persistent pool.
|
||||||
*/
|
*/
|
||||||
struct service* service; /**< The related service */
|
SERVICE* service; /**< The related service */
|
||||||
void* data; /**< Specific client data, shared between DCBs of this session */
|
void* data; /**< Specific client data, shared between DCBs of this session */
|
||||||
void* authenticator_data; /**< The authenticator data for this DCB */
|
void* authenticator_data; /**< The authenticator data for this DCB */
|
||||||
DCB_CALLBACK* callbacks; /**< The list of callbacks for the DCB */
|
DCB_CALLBACK* callbacks; /**< The list of callbacks for the DCB */
|
||||||
@ -260,7 +261,7 @@ void dcb_global_init();
|
|||||||
|
|
||||||
int dcb_write(DCB*, GWBUF*);
|
int dcb_write(DCB*, GWBUF*);
|
||||||
DCB* dcb_accept(DCB* listener);
|
DCB* dcb_accept(DCB* listener);
|
||||||
DCB* dcb_alloc(dcb_role_t, struct servlistener*);
|
DCB* dcb_alloc(dcb_role_t, SERV_LISTENER*);
|
||||||
DCB* dcb_connect(struct server*, struct session*, const char*);
|
DCB* dcb_connect(struct server*, struct session*, const char*);
|
||||||
int dcb_read(DCB*, GWBUF**, int);
|
int dcb_read(DCB*, GWBUF**, int);
|
||||||
int dcb_drain_writeq(DCB*);
|
int dcb_drain_writeq(DCB*);
|
||||||
|
@ -1,162 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2018 MariaDB Corporation Ab
|
|
||||||
*
|
|
||||||
* Use of this software is governed by the Business Source License included
|
|
||||||
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
|
|
||||||
*
|
|
||||||
* Change Date: 2022-01-01
|
|
||||||
*
|
|
||||||
* On the date above, in accordance with the Business Source License, use
|
|
||||||
* of this software will be governed by version 2 or later of the General
|
|
||||||
* Public License.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file listener.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <maxscale/cdefs.h>
|
|
||||||
#include <maxbase/jansson.h>
|
|
||||||
#include <maxscale/protocol.h>
|
|
||||||
#include <maxscale/ssl.h>
|
|
||||||
|
|
||||||
MXS_BEGIN_DECLS
|
|
||||||
|
|
||||||
struct dcb;
|
|
||||||
struct service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The servlistener structure is used to link a service to the protocols that
|
|
||||||
* are used to support that service. It defines the name of the protocol module
|
|
||||||
* that should be loaded to support the client connection and the port that the
|
|
||||||
* protocol should use to listen for incoming client connections.
|
|
||||||
*/
|
|
||||||
typedef struct servlistener
|
|
||||||
{
|
|
||||||
char* name; /**< Name of the listener */
|
|
||||||
char* protocol; /**< Protocol module to load */
|
|
||||||
unsigned short port; /**< Port to listen on */
|
|
||||||
char* address; /**< Address to listen with */
|
|
||||||
char* authenticator; /**< Name of authenticator */
|
|
||||||
char* auth_options; /**< Authenticator options */
|
|
||||||
void* auth_instance; /**< Authenticator instance created in MXS_AUTHENTICATOR::initialize()
|
|
||||||
* */
|
|
||||||
SSL_LISTENER* ssl; /**< Structure of SSL data or NULL */
|
|
||||||
struct dcb* listener; /**< The DCB for the listener */
|
|
||||||
struct users* users; /**< The user data for this listener */
|
|
||||||
struct service* service; /**< The service which used by this listener */
|
|
||||||
pthread_mutex_t lock;
|
|
||||||
int active; /**< True if the port has not been deleted */
|
|
||||||
struct servlistener* next; /**< Next service protocol */
|
|
||||||
} SERV_LISTENER; // TODO: Rename to LISTENER
|
|
||||||
|
|
||||||
typedef struct listener_iterator
|
|
||||||
{
|
|
||||||
SERV_LISTENER* current;
|
|
||||||
} LISTENER_ITERATOR;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Serialize a listener to a file
|
|
||||||
*
|
|
||||||
* This converts @c listener into an INI format file. This allows created listeners
|
|
||||||
* to be persisted to disk. This will replace any existing files with the same
|
|
||||||
* name.
|
|
||||||
*
|
|
||||||
* @param listener Listener to serialize
|
|
||||||
* @return True if the serialization of the listener was successful, false if it fails
|
|
||||||
*/
|
|
||||||
bool listener_serialize(const SERV_LISTENER* listener);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Convert listener to JSON
|
|
||||||
*
|
|
||||||
* @param listener Listener to convert
|
|
||||||
*
|
|
||||||
* @return Converted listener
|
|
||||||
*/
|
|
||||||
json_t* listener_to_json(const SERV_LISTENER* listener);
|
|
||||||
|
|
||||||
SERV_LISTENER* listener_alloc(struct service* service,
|
|
||||||
const char* name,
|
|
||||||
const char* protocol,
|
|
||||||
const char* address,
|
|
||||||
unsigned short port,
|
|
||||||
const char* authenticator,
|
|
||||||
const char* auth_options,
|
|
||||||
SSL_LISTENER* ssl);
|
|
||||||
void listener_free(SERV_LISTENER* listener);
|
|
||||||
int listener_set_ssl_version(SSL_LISTENER* ssl_listener, const char* version);
|
|
||||||
void listener_set_certificates(SSL_LISTENER* ssl_listener, char* cert, char* key, char* ca_cert);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize SSL configuration
|
|
||||||
*
|
|
||||||
* This sets up the generated RSA encryption keys, chooses the listener
|
|
||||||
* encryption level and configures the listener certificate, private key and
|
|
||||||
* certificate authority file.
|
|
||||||
*
|
|
||||||
* @note This function should not be called directly, use config_create_ssl() instead
|
|
||||||
*
|
|
||||||
* @todo Combine this with config_create_ssl() into one function
|
|
||||||
*
|
|
||||||
* @param ssl SSL configuration to initialize
|
|
||||||
*
|
|
||||||
* @return True on success, false on error
|
|
||||||
*/
|
|
||||||
bool SSL_LISTENER_init(SSL_LISTENER* ssl);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Free an SSL_LISTENER
|
|
||||||
*
|
|
||||||
* @param ssl SSL_LISTENER to free
|
|
||||||
*/
|
|
||||||
void SSL_LISTENER_free(SSL_LISTENER* ssl);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if listener is active
|
|
||||||
*
|
|
||||||
* @param listener Listener to check
|
|
||||||
*
|
|
||||||
* @return True if listener is active
|
|
||||||
*/
|
|
||||||
bool listener_is_active(SERV_LISTENER* listener);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Modify listener active state
|
|
||||||
*
|
|
||||||
* @param listener Listener to modify
|
|
||||||
* @param active True to activate, false to disable
|
|
||||||
*/
|
|
||||||
void listener_set_active(SERV_LISTENER* listener, bool active);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Initialize a listener iterator for iterating service listeners
|
|
||||||
*
|
|
||||||
* @param service Service whose listeners are iterated
|
|
||||||
* @param iter Pointer to iterator to initialize
|
|
||||||
*
|
|
||||||
* @return The first value pointed by the iterator
|
|
||||||
*/
|
|
||||||
SERV_LISTENER* listener_iterator_init(const struct service* service, LISTENER_ITERATOR* iter);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the next listener
|
|
||||||
*
|
|
||||||
* @param iter Listener iterator
|
|
||||||
*
|
|
||||||
* @return The next listener or NULL on end of list
|
|
||||||
*/
|
|
||||||
SERV_LISTENER* listener_iterator_next(LISTENER_ITERATOR* iter);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get listener state as a string
|
|
||||||
*
|
|
||||||
* @param listener Listener to inspect
|
|
||||||
*
|
|
||||||
* @return State of the listener as a string
|
|
||||||
*/
|
|
||||||
const char* listener_state_to_string(const SERV_LISTENER* listener);
|
|
||||||
|
|
||||||
MXS_END_DECLS
|
|
213
include/maxscale/listener.hh
Normal file
213
include/maxscale/listener.hh
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2018 MariaDB Corporation Ab
|
||||||
|
*
|
||||||
|
* Use of this software is governed by the Business Source License included
|
||||||
|
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
|
||||||
|
*
|
||||||
|
* Change Date: 2022-01-01
|
||||||
|
*
|
||||||
|
* On the date above, in accordance with the Business Source License, use
|
||||||
|
* of this software will be governed by version 2 or later of the General
|
||||||
|
* Public License.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <maxscale/ccdefs.hh>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <maxbase/jansson.h>
|
||||||
|
#include <maxscale/protocol.h>
|
||||||
|
#include <maxscale/ssl.h>
|
||||||
|
#include <maxscale/service.hh>
|
||||||
|
|
||||||
|
struct dcb;
|
||||||
|
class SERVICE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Listener class is used to link a network port to a service. It defines the name of the
|
||||||
|
* protocol module that should be loaded as well as the authenticator that is used.
|
||||||
|
*/
|
||||||
|
// TODO: Rename to Listener
|
||||||
|
class SERV_LISTENER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SERV_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& auth_opts, void* auth_instance, SSL_LISTENER* ssl);
|
||||||
|
~SERV_LISTENER();
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::string name; /**< Name of the listener */
|
||||||
|
std::string protocol; /**< Protocol module to load */
|
||||||
|
uint16_t port; /**< Port to listen on */
|
||||||
|
std::string address; /**< Address to listen with */
|
||||||
|
std::string authenticator;/**< Name of authenticator */
|
||||||
|
std::string auth_options; /**< Authenticator options */
|
||||||
|
void* auth_instance;/**< Authenticator instance */
|
||||||
|
SSL_LISTENER* ssl; /**< Structure of SSL data or NULL */
|
||||||
|
struct dcb* listener; /**< The DCB for the listener */
|
||||||
|
struct users* users; /**< The user data for this listener */
|
||||||
|
SERVICE* service; /**< The service which used by this listener */
|
||||||
|
int active; /**< True if the port has not been deleted */
|
||||||
|
SERV_LISTENER* next; /**< Next service protocol */
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct listener_iterator
|
||||||
|
{
|
||||||
|
SERV_LISTENER* current;
|
||||||
|
} LISTENER_ITERATOR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Serialize a listener to a file
|
||||||
|
*
|
||||||
|
* This converts @c listener into an INI format file. This allows created listeners
|
||||||
|
* to be persisted to disk. This will replace any existing files with the same
|
||||||
|
* name.
|
||||||
|
*
|
||||||
|
* @param listener Listener to serialize
|
||||||
|
* @return True if the serialization of the listener was successful, false if it fails
|
||||||
|
*/
|
||||||
|
bool listener_serialize(const SERV_LISTENER* listener);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert listener to JSON
|
||||||
|
*
|
||||||
|
* @param listener Listener to convert
|
||||||
|
*
|
||||||
|
* @return Converted listener
|
||||||
|
*/
|
||||||
|
json_t* listener_to_json(const SERV_LISTENER* listener);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new listener
|
||||||
|
*
|
||||||
|
* @param service Service where the listener points to
|
||||||
|
* @param name Name of the listener
|
||||||
|
* @param protocol Protocol module to use
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
SERV_LISTENER* listener_alloc(SERVICE* service,
|
||||||
|
const char* name,
|
||||||
|
const char* protocol,
|
||||||
|
const char* address,
|
||||||
|
unsigned short port,
|
||||||
|
const char* authenticator,
|
||||||
|
const char* auth_options,
|
||||||
|
SSL_LISTENER* ssl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free a listener
|
||||||
|
*
|
||||||
|
* The listener must be destroyed before it can be freed.
|
||||||
|
*
|
||||||
|
* @param listener Listener to free
|
||||||
|
*/
|
||||||
|
void listener_free(SERV_LISTENER* listener);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy a listener
|
||||||
|
*
|
||||||
|
* This deactivates the listener and closes the network port it listens on. Once destroyed, the listener
|
||||||
|
* can no longer be used.
|
||||||
|
*
|
||||||
|
* @param listener Listener to destroy
|
||||||
|
*/
|
||||||
|
void listener_destroy(SERV_LISTENER* listener);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop a listener
|
||||||
|
*
|
||||||
|
* @param listener Listener to stop
|
||||||
|
*
|
||||||
|
* @return True if listener was successfully stopped
|
||||||
|
*/
|
||||||
|
bool listener_stop(SERV_LISTENER* listener);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a stopped listener
|
||||||
|
*
|
||||||
|
* @param listener Listener to start
|
||||||
|
*
|
||||||
|
* @return True if listener was successfully started
|
||||||
|
*/
|
||||||
|
bool listener_start(SERV_LISTENER* listener);
|
||||||
|
|
||||||
|
int listener_set_ssl_version(SSL_LISTENER* ssl_listener, const char* version);
|
||||||
|
void listener_set_certificates(SSL_LISTENER* ssl_listener, char* cert, char* key, char* ca_cert);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize SSL configuration
|
||||||
|
*
|
||||||
|
* This sets up the generated RSA encryption keys, chooses the listener
|
||||||
|
* encryption level and configures the listener certificate, private key and
|
||||||
|
* certificate authority file.
|
||||||
|
*
|
||||||
|
* @note This function should not be called directly, use config_create_ssl() instead
|
||||||
|
*
|
||||||
|
* @todo Combine this with config_create_ssl() into one function
|
||||||
|
*
|
||||||
|
* @param ssl SSL configuration to initialize
|
||||||
|
*
|
||||||
|
* @return True on success, false on error
|
||||||
|
*/
|
||||||
|
bool SSL_LISTENER_init(SSL_LISTENER* ssl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free an SSL_LISTENER
|
||||||
|
*
|
||||||
|
* @param ssl SSL_LISTENER to free
|
||||||
|
*/
|
||||||
|
void SSL_LISTENER_free(SSL_LISTENER* ssl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if listener is active
|
||||||
|
*
|
||||||
|
* @param listener Listener to check
|
||||||
|
*
|
||||||
|
* @return True if listener is active
|
||||||
|
*/
|
||||||
|
bool listener_is_active(SERV_LISTENER* listener);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Modify listener active state
|
||||||
|
*
|
||||||
|
* @param listener Listener to modify
|
||||||
|
* @param active True to activate, false to disable
|
||||||
|
*/
|
||||||
|
void listener_set_active(SERV_LISTENER* listener, bool active);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize a listener iterator for iterating service listeners
|
||||||
|
*
|
||||||
|
* @param service Service whose listeners are iterated
|
||||||
|
* @param iter Pointer to iterator to initialize
|
||||||
|
*
|
||||||
|
* @return The first value pointed by the iterator
|
||||||
|
*/
|
||||||
|
SERV_LISTENER* listener_iterator_init(const SERVICE* service, LISTENER_ITERATOR* iter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the next listener
|
||||||
|
*
|
||||||
|
* @param iter Listener iterator
|
||||||
|
*
|
||||||
|
* @return The next listener or NULL on end of list
|
||||||
|
*/
|
||||||
|
SERV_LISTENER* listener_iterator_next(LISTENER_ITERATOR* iter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get listener state as a string
|
||||||
|
*
|
||||||
|
* @param listener Listener to inspect
|
||||||
|
*
|
||||||
|
* @return State of the listener as a string
|
||||||
|
*/
|
||||||
|
const char* listener_state_to_string(const SERV_LISTENER* listener);
|
@ -19,7 +19,7 @@
|
|||||||
#include <maxscale/cdefs.h>
|
#include <maxscale/cdefs.h>
|
||||||
#include <maxbase/jansson.h>
|
#include <maxbase/jansson.h>
|
||||||
#include <maxscale/dcb.h>
|
#include <maxscale/dcb.h>
|
||||||
#include <maxscale/listener.h>
|
#include <maxscale/listener.hh>
|
||||||
#include <maxscale/service.hh>
|
#include <maxscale/service.hh>
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
|
@ -47,11 +47,11 @@ bool authenticator_init(void** dest, const char* authenticator, const char* opti
|
|||||||
else if (func->initialize)
|
else if (func->initialize)
|
||||||
{
|
{
|
||||||
char* optarray[AUTHENTICATOR_MAX_OPTIONS + 1];
|
char* optarray[AUTHENTICATOR_MAX_OPTIONS + 1];
|
||||||
size_t optlen = options ? strlen(options) : 0;
|
size_t optlen = options && *options ? strlen(options) : 0;
|
||||||
char optcopy[optlen + 1];
|
char optcopy[optlen + 1];
|
||||||
int optcount = 0;
|
int optcount = 0;
|
||||||
|
|
||||||
if (options)
|
if (options && *options)
|
||||||
{
|
{
|
||||||
strcpy(optcopy, options);
|
strcpy(optcopy, options);
|
||||||
char* opt = optcopy;
|
char* opt = optcopy;
|
||||||
|
@ -327,9 +327,9 @@ const MXS_MODULE_PARAM config_listener_params[] =
|
|||||||
{CN_PORT, MXS_MODULE_PARAM_COUNT}, // Either port or socket,
|
{CN_PORT, MXS_MODULE_PARAM_COUNT}, // Either port or socket,
|
||||||
// checked when created
|
// checked when created
|
||||||
{CN_SOCKET, MXS_MODULE_PARAM_STRING},
|
{CN_SOCKET, MXS_MODULE_PARAM_STRING},
|
||||||
{CN_AUTHENTICATOR_OPTIONS, MXS_MODULE_PARAM_STRING},
|
{CN_AUTHENTICATOR_OPTIONS, MXS_MODULE_PARAM_STRING, ""},
|
||||||
{CN_ADDRESS, MXS_MODULE_PARAM_STRING, "::"},
|
{CN_ADDRESS, MXS_MODULE_PARAM_STRING, "::"},
|
||||||
{CN_AUTHENTICATOR, MXS_MODULE_PARAM_STRING},
|
{CN_AUTHENTICATOR, MXS_MODULE_PARAM_STRING, "MySQLAuth"},
|
||||||
{CN_SSL, MXS_MODULE_PARAM_ENUM, "false",
|
{CN_SSL, MXS_MODULE_PARAM_ENUM, "false",
|
||||||
MXS_MODULE_OPT_ENUM_UNIQUE,
|
MXS_MODULE_OPT_ENUM_UNIQUE,
|
||||||
ssl_values},
|
ssl_values},
|
||||||
@ -3860,7 +3860,7 @@ int create_new_listener(CONFIG_CONTEXT* obj)
|
|||||||
"listener '%s' already listens on the %s %s.",
|
"listener '%s' already listens on the %s %s.",
|
||||||
obj->object,
|
obj->object,
|
||||||
service->name,
|
service->name,
|
||||||
l->name,
|
l->name.c_str(),
|
||||||
socket ? "socket" : "port",
|
socket ? "socket" : "port",
|
||||||
socket ? socket : port);
|
socket ? socket : port);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
#include <maxbase/atomic.hh>
|
#include <maxbase/atomic.hh>
|
||||||
#include <maxscale/clock.h>
|
#include <maxscale/clock.h>
|
||||||
#include <maxscale/limits.h>
|
#include <maxscale/limits.h>
|
||||||
#include <maxscale/listener.h>
|
#include <maxscale/listener.hh>
|
||||||
#include <maxscale/log.h>
|
#include <maxscale/log.h>
|
||||||
#include <maxscale/poll.h>
|
#include <maxscale/poll.h>
|
||||||
#include <maxscale/router.h>
|
#include <maxscale/router.h>
|
||||||
@ -2451,9 +2451,9 @@ DCB* dcb_accept(DCB* dcb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
memcpy(&client_dcb->func, protocol_funcs, sizeof(MXS_PROTOCOL));
|
memcpy(&client_dcb->func, protocol_funcs, sizeof(MXS_PROTOCOL));
|
||||||
if (dcb->listener->authenticator)
|
if (!dcb->listener->authenticator.empty())
|
||||||
{
|
{
|
||||||
authenticator_name = dcb->listener->authenticator;
|
authenticator_name = dcb->listener->authenticator.c_str();
|
||||||
}
|
}
|
||||||
else if (client_dcb->func.auth_default != NULL)
|
else if (client_dcb->func.auth_default != NULL)
|
||||||
{
|
{
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <maxscale/listener.h>
|
#include <maxscale/listener.hh>
|
||||||
#include <maxscale/paths.h>
|
#include <maxscale/paths.h>
|
||||||
#include <maxscale/ssl.h>
|
#include <maxscale/ssl.h>
|
||||||
#include <maxscale/protocol.h>
|
#include <maxscale/protocol.h>
|
||||||
@ -47,6 +47,40 @@ static RSA* rsa_1024 = NULL;
|
|||||||
|
|
||||||
static RSA* tmp_rsa_callback(SSL* s, int is_export, int keylength);
|
static RSA* tmp_rsa_callback(SSL* s, int is_export, int keylength);
|
||||||
|
|
||||||
|
SERV_LISTENER::SERV_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& auth_opts, void* auth_instance, SSL_LISTENER* ssl)
|
||||||
|
: name(name)
|
||||||
|
, protocol(protocol)
|
||||||
|
, port(port)
|
||||||
|
, address(address)
|
||||||
|
, authenticator(authenticator)
|
||||||
|
, auth_options(auth_opts)
|
||||||
|
, auth_instance(auth_instance)
|
||||||
|
, ssl(ssl)
|
||||||
|
, listener(nullptr)
|
||||||
|
, users(nullptr)
|
||||||
|
, service(service)
|
||||||
|
, active(1)
|
||||||
|
, next(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SERV_LISTENER::~SERV_LISTENER()
|
||||||
|
{
|
||||||
|
if (users)
|
||||||
|
{
|
||||||
|
users_free(users);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listener)
|
||||||
|
{
|
||||||
|
dcb_close(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
SSL_LISTENER_free(ssl);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new listener structure
|
* Create a new listener structure
|
||||||
*
|
*
|
||||||
@ -67,84 +101,27 @@ SERV_LISTENER* listener_alloc(SERVICE* service,
|
|||||||
const char* auth_options,
|
const char* auth_options,
|
||||||
SSL_LISTENER* ssl)
|
SSL_LISTENER* ssl)
|
||||||
{
|
{
|
||||||
char* my_address = NULL;
|
if (!authenticator)
|
||||||
if (address)
|
|
||||||
{
|
{
|
||||||
my_address = MXS_STRDUP(address);
|
if ((authenticator = get_default_authenticator(protocol)) == NULL)
|
||||||
if (!my_address)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char* my_auth_options = NULL;
|
|
||||||
|
|
||||||
if (auth_options && (my_auth_options = MXS_STRDUP(auth_options)) == NULL)
|
|
||||||
{
|
|
||||||
MXS_FREE(my_address);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* my_authenticator = NULL;
|
|
||||||
|
|
||||||
if (authenticator)
|
|
||||||
{
|
|
||||||
my_authenticator = MXS_STRDUP(authenticator);
|
|
||||||
}
|
|
||||||
else if ((authenticator = get_default_authenticator(protocol)) == NULL
|
|
||||||
|| (my_authenticator = MXS_STRDUP(authenticator)) == NULL)
|
|
||||||
{
|
{
|
||||||
MXS_ERROR("No authenticator defined for listener '%s' and could not get "
|
MXS_ERROR("No authenticator defined for listener '%s' and could not get "
|
||||||
"default authenticator for protocol '%s'.",
|
"default authenticator for protocol '%s'.", name, protocol);
|
||||||
name,
|
return nullptr;
|
||||||
protocol);
|
}
|
||||||
MXS_FREE(my_address);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void* auth_instance = NULL;
|
void* auth_instance = NULL;
|
||||||
|
|
||||||
if (!authenticator_init(&auth_instance, my_authenticator, my_auth_options))
|
if (!authenticator_init(&auth_instance, authenticator, auth_options))
|
||||||
{
|
{
|
||||||
MXS_ERROR("Failed to initialize authenticator module '%s' for "
|
MXS_ERROR("Failed to initialize authenticator module '%s' for listener '%s'.",
|
||||||
"listener '%s'.",
|
authenticator, name);
|
||||||
my_authenticator,
|
return nullptr;
|
||||||
name);
|
|
||||||
MXS_FREE(my_address);
|
|
||||||
MXS_FREE(my_authenticator);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char* my_protocol = MXS_STRDUP(protocol);
|
return new(std::nothrow) SERV_LISTENER(service, name, address, port, protocol, authenticator,
|
||||||
char* my_name = MXS_STRDUP(name);
|
auth_options, auth_instance, ssl);
|
||||||
SERV_LISTENER* proto = (SERV_LISTENER*)MXS_MALLOC(sizeof(SERV_LISTENER));
|
|
||||||
|
|
||||||
if (!my_protocol || !proto || !my_name || !my_authenticator)
|
|
||||||
{
|
|
||||||
MXS_FREE(my_authenticator);
|
|
||||||
MXS_FREE(my_protocol);
|
|
||||||
MXS_FREE(my_address);
|
|
||||||
MXS_FREE(my_name);
|
|
||||||
MXS_FREE(proto);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
proto->active = 1;
|
|
||||||
proto->name = my_name;
|
|
||||||
proto->listener = NULL;
|
|
||||||
proto->service = service;
|
|
||||||
proto->protocol = my_protocol;
|
|
||||||
proto->address = my_address;
|
|
||||||
proto->port = port;
|
|
||||||
proto->authenticator = my_authenticator;
|
|
||||||
proto->auth_options = my_auth_options;
|
|
||||||
proto->ssl = ssl;
|
|
||||||
proto->users = NULL;
|
|
||||||
proto->next = NULL;
|
|
||||||
proto->auth_instance = auth_instance;
|
|
||||||
pthread_mutex_init(&proto->lock, NULL);
|
|
||||||
|
|
||||||
return proto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -154,26 +131,7 @@ SERV_LISTENER* listener_alloc(SERVICE* service,
|
|||||||
*/
|
*/
|
||||||
void listener_free(SERV_LISTENER* listener)
|
void listener_free(SERV_LISTENER* listener)
|
||||||
{
|
{
|
||||||
if (listener)
|
delete listener;
|
||||||
{
|
|
||||||
if (listener->users)
|
|
||||||
{
|
|
||||||
users_free(listener->users);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listener->listener)
|
|
||||||
{
|
|
||||||
dcb_close(listener->listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
SSL_LISTENER_free(listener->ssl);
|
|
||||||
MXS_FREE(listener->address);
|
|
||||||
MXS_FREE(listener->authenticator);
|
|
||||||
MXS_FREE(listener->auth_options);
|
|
||||||
MXS_FREE(listener->name);
|
|
||||||
MXS_FREE(listener->protocol);
|
|
||||||
MXS_FREE(listener);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -480,24 +438,24 @@ static bool create_listener_config(const SERV_LISTENER* listener, const char* fi
|
|||||||
{
|
{
|
||||||
MXS_ERROR("Failed to open file '%s' when serializing listener '%s': %d, %s",
|
MXS_ERROR("Failed to open file '%s' when serializing listener '%s': %d, %s",
|
||||||
filename,
|
filename,
|
||||||
listener->name,
|
listener->name.c_str(),
|
||||||
errno,
|
errno,
|
||||||
mxs_strerror(errno));
|
mxs_strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Check for return values on all of the dprintf calls
|
// TODO: Check for return values on all of the dprintf calls
|
||||||
dprintf(file, "[%s]\n", listener->name);
|
dprintf(file, "[%s]\n", listener->name.c_str());
|
||||||
dprintf(file, "type=listener\n");
|
dprintf(file, "type=listener\n");
|
||||||
dprintf(file, "protocol=%s\n", listener->protocol);
|
dprintf(file, "protocol=%s\n", listener->protocol.c_str());
|
||||||
dprintf(file, "service=%s\n", listener->service->name);
|
dprintf(file, "service=%s\n", listener->service->name);
|
||||||
dprintf(file, "address=%s\n", listener->address);
|
dprintf(file, "address=%s\n", listener->address.c_str());
|
||||||
dprintf(file, "port=%u\n", listener->port);
|
dprintf(file, "port=%u\n", listener->port);
|
||||||
dprintf(file, "authenticator=%s\n", listener->authenticator);
|
dprintf(file, "authenticator=%s\n", listener->authenticator.c_str());
|
||||||
|
|
||||||
if (listener->auth_options)
|
if (!listener->auth_options.empty())
|
||||||
{
|
{
|
||||||
dprintf(file, "authenticator_options=%s\n", listener->auth_options);
|
dprintf(file, "authenticator_options=%s\n", listener->auth_options.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listener->ssl)
|
if (listener->ssl)
|
||||||
@ -518,7 +476,7 @@ bool listener_serialize(const SERV_LISTENER* listener)
|
|||||||
sizeof(filename),
|
sizeof(filename),
|
||||||
"%s/%s.cnf.tmp",
|
"%s/%s.cnf.tmp",
|
||||||
get_config_persistdir(),
|
get_config_persistdir(),
|
||||||
listener->name);
|
listener->name.c_str());
|
||||||
|
|
||||||
if (unlink(filename) == -1 && errno != ENOENT)
|
if (unlink(filename) == -1 && errno != ENOENT)
|
||||||
{
|
{
|
||||||
@ -555,11 +513,11 @@ bool listener_serialize(const SERV_LISTENER* listener)
|
|||||||
json_t* listener_to_json(const SERV_LISTENER* listener)
|
json_t* listener_to_json(const SERV_LISTENER* listener)
|
||||||
{
|
{
|
||||||
json_t* param = json_object();
|
json_t* param = json_object();
|
||||||
json_object_set_new(param, "address", json_string(listener->address));
|
json_object_set_new(param, "address", json_string(listener->address.c_str()));
|
||||||
json_object_set_new(param, "port", json_integer(listener->port));
|
json_object_set_new(param, "port", json_integer(listener->port));
|
||||||
json_object_set_new(param, "protocol", json_string(listener->protocol));
|
json_object_set_new(param, "protocol", json_string(listener->protocol.c_str()));
|
||||||
json_object_set_new(param, "authenticator", json_string(listener->authenticator));
|
json_object_set_new(param, "authenticator", json_string(listener->authenticator.c_str()));
|
||||||
json_object_set_new(param, "auth_options", json_string(listener->auth_options));
|
json_object_set_new(param, "auth_options", json_string(listener->auth_options.c_str()));
|
||||||
|
|
||||||
if (listener->ssl)
|
if (listener->ssl)
|
||||||
{
|
{
|
||||||
@ -589,7 +547,7 @@ json_t* listener_to_json(const SERV_LISTENER* listener)
|
|||||||
}
|
}
|
||||||
|
|
||||||
json_t* rval = json_object();
|
json_t* rval = json_object();
|
||||||
json_object_set_new(rval, CN_ID, json_string(listener->name));
|
json_object_set_new(rval, CN_ID, json_string(listener->name.c_str()));
|
||||||
json_object_set_new(rval, CN_TYPE, json_string(CN_LISTENERS));
|
json_object_set_new(rval, CN_TYPE, json_string(CN_LISTENERS));
|
||||||
json_object_set_new(rval, CN_ATTRIBUTES, attr);
|
json_object_set_new(rval, CN_ATTRIBUTES, attr);
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
#include <maxscale/dcb.h>
|
#include <maxscale/dcb.h>
|
||||||
#include <maxscale/paths.h>
|
#include <maxscale/paths.h>
|
||||||
#include <maxscale/housekeeper.h>
|
#include <maxscale/housekeeper.h>
|
||||||
#include <maxscale/listener.h>
|
#include <maxscale/listener.hh>
|
||||||
#include <maxscale/log.h>
|
#include <maxscale/log.h>
|
||||||
#include <maxscale/poll.h>
|
#include <maxscale/poll.h>
|
||||||
#include <maxscale/protocol.h>
|
#include <maxscale/protocol.h>
|
||||||
@ -351,7 +351,7 @@ static int serviceStartPort(Service* service, SERV_LISTENER* port)
|
|||||||
|
|
||||||
int listeners = 0;
|
int listeners = 0;
|
||||||
size_t config_bind_len =
|
size_t config_bind_len =
|
||||||
(port->address ? strlen(port->address) : ANY_IPV4_ADDRESS_LEN) + 1 + UINTLEN(port->port);
|
(!port->address.empty() ? port->address.length() : ANY_IPV4_ADDRESS_LEN) + 1 + UINTLEN(port->port);
|
||||||
char config_bind[config_bind_len + 1]; // +1 for NULL
|
char config_bind[config_bind_len + 1]; // +1 for NULL
|
||||||
MXS_PROTOCOL* funcs;
|
MXS_PROTOCOL* funcs;
|
||||||
|
|
||||||
@ -375,10 +375,10 @@ static int serviceStartPort(Service* service, SERV_LISTENER* port)
|
|||||||
|
|
||||||
port->listener->service = service;
|
port->listener->service = service;
|
||||||
|
|
||||||
if ((funcs = (MXS_PROTOCOL*)load_module(port->protocol, MODULE_PROTOCOL)) == NULL)
|
if ((funcs = (MXS_PROTOCOL*)load_module(port->protocol.c_str(), MODULE_PROTOCOL)) == NULL)
|
||||||
{
|
{
|
||||||
MXS_ERROR("Unable to load protocol module %s. Listener for service %s not started.",
|
MXS_ERROR("Unable to load protocol module %s. Listener for service %s not started.",
|
||||||
port->protocol,
|
port->protocol.c_str(),
|
||||||
service->name);
|
service->name);
|
||||||
close_port(port);
|
close_port(port);
|
||||||
return 0;
|
return 0;
|
||||||
@ -388,9 +388,9 @@ static int serviceStartPort(Service* service, SERV_LISTENER* port)
|
|||||||
|
|
||||||
const char* authenticator_name = "NullAuthDeny";
|
const char* authenticator_name = "NullAuthDeny";
|
||||||
|
|
||||||
if (port->authenticator)
|
if (!port->authenticator.empty())
|
||||||
{
|
{
|
||||||
authenticator_name = port->authenticator;
|
authenticator_name = port->authenticator.c_str();
|
||||||
}
|
}
|
||||||
else if (port->listener->func.auth_default)
|
else if (port->listener->func.auth_default)
|
||||||
{
|
{
|
||||||
@ -403,13 +403,13 @@ static int serviceStartPort(Service* service, SERV_LISTENER* port)
|
|||||||
{
|
{
|
||||||
MXS_ERROR("Failed to load authenticator module '%s' for listener '%s'",
|
MXS_ERROR("Failed to load authenticator module '%s' for listener '%s'",
|
||||||
authenticator_name,
|
authenticator_name,
|
||||||
port->name);
|
port->name.c_str());
|
||||||
close_port(port);
|
close_port(port);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add protocol and authenticator capabilities from the listener
|
// Add protocol and authenticator capabilities from the listener
|
||||||
const MXS_MODULE* proto_mod = get_module(port->protocol, MODULE_PROTOCOL);
|
const MXS_MODULE* proto_mod = get_module(port->protocol.c_str(), MODULE_PROTOCOL);
|
||||||
const MXS_MODULE* auth_mod = get_module(authenticator_name, MODULE_AUTHENTICATOR);
|
const MXS_MODULE* auth_mod = get_module(authenticator_name, MODULE_AUTHENTICATOR);
|
||||||
mxb_assert(proto_mod && auth_mod);
|
mxb_assert(proto_mod && auth_mod);
|
||||||
service->capabilities |= proto_mod->module_capabilities | auth_mod->module_capabilities;
|
service->capabilities |= proto_mod->module_capabilities | auth_mod->module_capabilities;
|
||||||
@ -421,9 +421,9 @@ static int serviceStartPort(Service* service, SERV_LISTENER* port)
|
|||||||
* listeners aren't normal DCBs, we can skip that.
|
* listeners aren't normal DCBs, we can skip that.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (port->address)
|
if (!port->address.empty())
|
||||||
{
|
{
|
||||||
sprintf(config_bind, "%s|%d", port->address, port->port);
|
sprintf(config_bind, "%s|%d", port->address.c_str(), port->port);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -439,7 +439,7 @@ static int serviceStartPort(Service* service, SERV_LISTENER* port)
|
|||||||
MXS_ERROR("[%s] Fatal error when loading users for listener '%s', "
|
MXS_ERROR("[%s] Fatal error when loading users for listener '%s', "
|
||||||
"service is not started.",
|
"service is not started.",
|
||||||
service->name,
|
service->name,
|
||||||
port->name);
|
port->name.c_str());
|
||||||
close_port(port);
|
close_port(port);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -447,7 +447,7 @@ static int serviceStartPort(Service* service, SERV_LISTENER* port)
|
|||||||
MXS_WARNING("[%s] Failed to load users for listener '%s', authentication"
|
MXS_WARNING("[%s] Failed to load users for listener '%s', authentication"
|
||||||
" might not work.",
|
" might not work.",
|
||||||
service->name,
|
service->name,
|
||||||
port->name);
|
port->name.c_str());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -594,7 +594,7 @@ bool serviceStopListener(SERVICE* svc, const char* name)
|
|||||||
for (SERV_LISTENER* listener = listener_iterator_init(service, &iter);
|
for (SERV_LISTENER* listener = listener_iterator_init(service, &iter);
|
||||||
listener; listener = listener_iterator_next(&iter))
|
listener; listener = listener_iterator_next(&iter))
|
||||||
{
|
{
|
||||||
if (listener_is_active(listener) && strcmp(listener->name, name) == 0)
|
if (listener_is_active(listener) && listener->name == name)
|
||||||
{
|
{
|
||||||
if (poll_remove_dcb(listener->listener) == 0)
|
if (poll_remove_dcb(listener->listener) == 0)
|
||||||
{
|
{
|
||||||
@ -617,7 +617,7 @@ bool serviceStartListener(SERVICE* svc, const char* name)
|
|||||||
for (SERV_LISTENER* listener = listener_iterator_init(service, &iter);
|
for (SERV_LISTENER* listener = listener_iterator_init(service, &iter);
|
||||||
listener; listener = listener_iterator_next(&iter))
|
listener; listener = listener_iterator_next(&iter))
|
||||||
{
|
{
|
||||||
if (listener_is_active(listener) && strcmp(listener->name, name) == 0)
|
if (listener_is_active(listener) && listener->name == name)
|
||||||
{
|
{
|
||||||
if (listener->listener && listener->listener->session->state == SESSION_STATE_LISTENER_STOPPED
|
if (listener->listener && listener->listener->session->state == SESSION_STATE_LISTENER_STOPPED
|
||||||
&& poll_add_dcb(listener->listener) == 0)
|
&& poll_add_dcb(listener->listener) == 0)
|
||||||
@ -752,7 +752,7 @@ bool service_remove_listener(Service* service, const char* target)
|
|||||||
for (SERV_LISTENER* listener = listener_iterator_init(service, &iter);
|
for (SERV_LISTENER* listener = listener_iterator_init(service, &iter);
|
||||||
listener; listener = listener_iterator_next(&iter))
|
listener; listener = listener_iterator_next(&iter))
|
||||||
{
|
{
|
||||||
if (listener_is_active(listener) && strcmp(listener->name, target) == 0)
|
if (listener_is_active(listener) && listener->name == target)
|
||||||
{
|
{
|
||||||
listener_set_active(listener, false);
|
listener_set_active(listener, false);
|
||||||
|
|
||||||
@ -821,28 +821,10 @@ SERV_LISTENER* service_find_listener(Service* service,
|
|||||||
for (SERV_LISTENER* listener = listener_iterator_init(service, &iter);
|
for (SERV_LISTENER* listener = listener_iterator_init(service, &iter);
|
||||||
listener; listener = listener_iterator_next(&iter))
|
listener; listener = listener_iterator_next(&iter))
|
||||||
{
|
{
|
||||||
if (listener_is_active(listener))
|
if (listener_is_active(listener) && port == listener->port)
|
||||||
{
|
{
|
||||||
bool is_same_port = false;
|
if ((!address && listener->address.empty()) || listener->address == address
|
||||||
|
|| (!socket && listener->address.empty()) || listener->address == socket)
|
||||||
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 listener;
|
||||||
}
|
}
|
||||||
@ -872,17 +854,14 @@ bool serviceHasListener(Service* service,
|
|||||||
for (SERV_LISTENER* listener = listener_iterator_init(service, &iter);
|
for (SERV_LISTENER* listener = listener_iterator_init(service, &iter);
|
||||||
listener; listener = listener_iterator_next(&iter))
|
listener; listener = listener_iterator_next(&iter))
|
||||||
{
|
{
|
||||||
if (listener_is_active(listener)
|
if (listener_is_active(listener) && listener->port == port)
|
||||||
&& // Listener with same name exists
|
{
|
||||||
(strcmp(listener->name, name) == 0
|
if ((!address && listener->address.empty()) || listener->address == address)
|
||||||
|| // Listener listening on the same interface and port exists
|
|
||||||
((strcmp(listener->protocol, protocol) == 0 && listener->port == port
|
|
||||||
&& ((address && listener->address && strcmp(listener->address, address) == 0)
|
|
||||||
|| (address == NULL && listener->address == NULL))))))
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -894,7 +873,7 @@ bool service_has_named_listener(Service* service, const char* name)
|
|||||||
for (SERV_LISTENER* listener = listener_iterator_init(service, &iter);
|
for (SERV_LISTENER* listener = listener_iterator_init(service, &iter);
|
||||||
listener; listener = listener_iterator_next(&iter))
|
listener; listener = listener_iterator_next(&iter))
|
||||||
{
|
{
|
||||||
if (listener_is_active(listener) && strcmp(listener->name, name) == 0)
|
if (listener_is_active(listener) && listener->name == name)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1403,10 +1382,10 @@ void dListListeners(DCB* dcb)
|
|||||||
{
|
{
|
||||||
dcb_printf(dcb,
|
dcb_printf(dcb,
|
||||||
"%-20s | %-19s | %-18s | %-15s | %5d | %s\n",
|
"%-20s | %-19s | %-18s | %-15s | %5d | %s\n",
|
||||||
listener->name,
|
listener->name.c_str(),
|
||||||
service->name,
|
service->name,
|
||||||
listener->protocol,
|
listener->protocol.c_str(),
|
||||||
(listener && listener->address) ? listener->address : "*",
|
(listener && !listener->address.empty()) ? listener->address.c_str() : "*",
|
||||||
listener->port,
|
listener->port,
|
||||||
listener_state_to_string(listener));
|
listener_state_to_string(listener));
|
||||||
}
|
}
|
||||||
@ -1473,7 +1452,7 @@ bool Service::refresh_users()
|
|||||||
MXS_ERROR("[%s] Fatal error when loading users for listener '%s',"
|
MXS_ERROR("[%s] Fatal error when loading users for listener '%s',"
|
||||||
" authentication will not work.",
|
" authentication will not work.",
|
||||||
m_name.c_str(),
|
m_name.c_str(),
|
||||||
listener->name);
|
listener->name.c_str());
|
||||||
ret = false;
|
ret = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1481,7 +1460,7 @@ bool Service::refresh_users()
|
|||||||
MXS_WARNING("[%s] Failed to load users for listener '%s', authentication"
|
MXS_WARNING("[%s] Failed to load users for listener '%s', authentication"
|
||||||
" might not work.",
|
" might not work.",
|
||||||
m_name.c_str(),
|
m_name.c_str(),
|
||||||
listener->name);
|
listener->name.c_str());
|
||||||
ret = false;
|
ret = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1938,7 +1917,7 @@ void service_print_users(DCB* dcb, const SERVICE* service)
|
|||||||
if (listener_is_active(listener) && listener->listener
|
if (listener_is_active(listener) && listener->listener
|
||||||
&& listener->listener->authfunc.diagnostic)
|
&& listener->listener->authfunc.diagnostic)
|
||||||
{
|
{
|
||||||
dcb_printf(dcb, "User names (%s): ", listener->name);
|
dcb_printf(dcb, "User names (%s): ", listener->name.c_str());
|
||||||
|
|
||||||
listener->listener->authfunc.diagnostic(dcb, listener);
|
listener->listener->authfunc.diagnostic(dcb, listener);
|
||||||
|
|
||||||
@ -2048,7 +2027,7 @@ static json_t* service_listener_json_data(const SERVICE* service, const char* na
|
|||||||
for (SERV_LISTENER* listener = listener_iterator_init(service, &iter);
|
for (SERV_LISTENER* listener = listener_iterator_init(service, &iter);
|
||||||
listener; listener = listener_iterator_next(&iter))
|
listener; listener = listener_iterator_next(&iter))
|
||||||
{
|
{
|
||||||
if (listener_is_active(listener) && strcmp(listener->name, name) == 0)
|
if (listener_is_active(listener) && listener->name == name)
|
||||||
{
|
{
|
||||||
return listener_to_json(listener);
|
return listener_to_json(listener);
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <maxscale/config.hh>
|
#include <maxscale/config.hh>
|
||||||
#include <maxscale/listener.h>
|
#include <maxscale/listener.hh>
|
||||||
#include <maxscale/routingworker.hh>
|
#include <maxscale/routingworker.hh>
|
||||||
|
|
||||||
#include "../dcb.cc"
|
#include "../dcb.cc"
|
||||||
@ -48,10 +48,10 @@
|
|||||||
static int test1()
|
static int test1()
|
||||||
{
|
{
|
||||||
DCB* dcb;
|
DCB* dcb;
|
||||||
SERV_LISTENER dummy;
|
SERV_LISTENER* dummy = nullptr;
|
||||||
/* Single buffer tests */
|
/* Single buffer tests */
|
||||||
fprintf(stderr, "testdcb : creating buffer with type DCB_ROLE_INTERNAL");
|
fprintf(stderr, "testdcb : creating buffer with type DCB_ROLE_INTERNAL");
|
||||||
dcb = dcb_alloc(DCB_ROLE_INTERNAL, &dummy);
|
dcb = dcb_alloc(DCB_ROLE_INTERNAL, dummy);
|
||||||
printDCB(dcb);
|
printDCB(dcb);
|
||||||
fprintf(stderr, "\t..done\nAllocated dcb.");
|
fprintf(stderr, "\t..done\nAllocated dcb.");
|
||||||
// TODO: Without running workers, the following will hang. As it does not
|
// TODO: Without running workers, the following will hang. As it does not
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <maxscale/dcb.h>
|
#include <maxscale/dcb.h>
|
||||||
#include <maxscale/listener.h>
|
#include <maxscale/listener.hh>
|
||||||
#include <maxscale/service.hh>
|
#include <maxscale/service.hh>
|
||||||
|
|
||||||
#include "test_utils.h"
|
#include "test_utils.h"
|
||||||
@ -49,7 +49,7 @@ static int test1()
|
|||||||
DCB* dcb;
|
DCB* dcb;
|
||||||
int result;
|
int result;
|
||||||
int eno = 0;
|
int eno = 0;
|
||||||
SERV_LISTENER dummy;
|
SERV_LISTENER* dummy = nullptr;
|
||||||
|
|
||||||
SERVICE service;
|
SERVICE service;
|
||||||
service.routerModule = (char*)"required by a check in dcb.cc";
|
service.routerModule = (char*)"required by a check in dcb.cc";
|
||||||
@ -59,7 +59,7 @@ static int test1()
|
|||||||
"testpoll : Initialise the polling system.");
|
"testpoll : Initialise the polling system.");
|
||||||
init_test_env(NULL);
|
init_test_env(NULL);
|
||||||
fprintf(stderr, "\t..done\nAdd a DCB");
|
fprintf(stderr, "\t..done\nAdd a DCB");
|
||||||
dcb = dcb_alloc(DCB_ROLE_CLIENT_HANDLER, &dummy);
|
dcb = dcb_alloc(DCB_ROLE_CLIENT_HANDLER, dummy);
|
||||||
|
|
||||||
if (dcb == NULL)
|
if (dcb == NULL)
|
||||||
{
|
{
|
||||||
|
@ -556,8 +556,6 @@ int cdc_replace_users(SERV_LISTENER* listener)
|
|||||||
int i = cdc_read_users(newusers, path);
|
int i = cdc_read_users(newusers, path);
|
||||||
USERS* oldusers = NULL;
|
USERS* oldusers = NULL;
|
||||||
|
|
||||||
pthread_mutex_lock(&listener->lock);
|
|
||||||
|
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
{
|
{
|
||||||
/** Successfully loaded at least one user */
|
/** Successfully loaded at least one user */
|
||||||
@ -578,8 +576,6 @@ int cdc_replace_users(SERV_LISTENER* listener)
|
|||||||
|
|
||||||
cdc_set_service_user(listener);
|
cdc_set_service_user(listener);
|
||||||
|
|
||||||
pthread_mutex_unlock(&listener->lock);
|
|
||||||
|
|
||||||
if (oldusers)
|
if (oldusers)
|
||||||
{
|
{
|
||||||
users_free(oldusers);
|
users_free(oldusers);
|
||||||
|
@ -635,8 +635,8 @@ static int mysql_auth_load_users(SERV_LISTENER* port)
|
|||||||
{
|
{
|
||||||
MXS_ERROR("[%s] Unable to load users for listener %s listening at [%s]:%d.",
|
MXS_ERROR("[%s] Unable to load users for listener %s listening at [%s]:%d.",
|
||||||
service->name,
|
service->name,
|
||||||
port->name,
|
port->name.c_str(),
|
||||||
port->address ? port->address : "::",
|
!port->address.empty() ? port->address.c_str() : "::",
|
||||||
port->port);
|
port->port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -673,7 +673,7 @@ static int mysql_auth_load_users(SERV_LISTENER* port)
|
|||||||
}
|
}
|
||||||
else if (loaded > 0 && first_load)
|
else if (loaded > 0 && first_load)
|
||||||
{
|
{
|
||||||
MXS_NOTICE("[%s] Loaded %d MySQL users for listener %s.", service->name, loaded, port->name);
|
MXS_NOTICE("[%s] Loaded %d MySQL users for listener %s.", service->name, loaded, port->name.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -206,7 +206,7 @@ static int httpd_read_event(DCB* dcb)
|
|||||||
/** If listener->authenticator is the default authenticator, it means that
|
/** If listener->authenticator is the default authenticator, it means that
|
||||||
* we don't need to check the user credentials. All other authenticators
|
* we don't need to check the user credentials. All other authenticators
|
||||||
* cause a 401 Unauthorized to be returned on the first try. */
|
* cause a 401 Unauthorized to be returned on the first try. */
|
||||||
bool auth_ok = strcmp(httpd_default_auth(), dcb->listener->authenticator) == 0;
|
bool auth_ok = httpd_default_auth() == dcb->listener->authenticator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the request headers
|
* Get the request headers
|
||||||
|
Reference in New Issue
Block a user