Move configuration context processing into subfunctions
The functions allow simple operations on configuration context objects. This makes it easier to understand what the code does and allows reuse of the configuration processing code.
This commit is contained in:
parent
11bee30f61
commit
b893ca7ba8
@ -32,6 +32,7 @@
|
||||
#include <limits.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <maxscale/gw_ssl.h>
|
||||
|
||||
MXS_BEGIN_DECLS
|
||||
|
||||
@ -129,13 +130,91 @@ typedef struct
|
||||
} GATEWAY_CONF;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Creates an empty configuration context
|
||||
*
|
||||
* @param section Context name
|
||||
* @return New context or NULL on memory allocation failure
|
||||
*/
|
||||
CONFIG_CONTEXT* config_context_create(const char *section);
|
||||
|
||||
/**
|
||||
* @brief Free a configuration context
|
||||
*
|
||||
* @param context The context to free
|
||||
*/
|
||||
void config_context_free(CONFIG_CONTEXT *context);
|
||||
|
||||
/**
|
||||
* @brief Get a configuration parameter
|
||||
*
|
||||
* @param params List of parameters
|
||||
* @param name Name of parameter to get
|
||||
* @return The parameter or NULL if the parameter was not found
|
||||
*/
|
||||
CONFIG_PARAMETER* config_get_param(CONFIG_PARAMETER* params, const char* name);
|
||||
|
||||
/**
|
||||
* @brief Add a parameter to a configuration context
|
||||
*
|
||||
* @param obj Context where the parameter should be added
|
||||
* @param key Key to add
|
||||
* @param value Value for the key
|
||||
* @return True on success, false on memory allocation error
|
||||
*/
|
||||
bool config_add_param(CONFIG_CONTEXT* obj, const char* key, const char* value);
|
||||
|
||||
/**
|
||||
* @brief Append to an existing parameter
|
||||
*
|
||||
* @param obj Configuration context
|
||||
* @param key Parameter name
|
||||
* @param value Value to append to the parameter
|
||||
* @return True on success, false on memory allocation error
|
||||
*/
|
||||
bool config_append_param(CONFIG_CONTEXT* obj, const char* key, const char* value);
|
||||
|
||||
/**
|
||||
* @brief Check if all SSL parameters are defined
|
||||
*
|
||||
* Helper function to check whether all of the required SSL parameters are defined
|
||||
* in the configuration context. The checked parameters are 'ssl', 'ssl_key',
|
||||
* 'ssl_cert' and 'ssl_ca_cert'. The 'ssl' parameter must also have a value of
|
||||
* 'required'.
|
||||
*
|
||||
* @param obj Configuration context
|
||||
* @return True if all required parameters are present
|
||||
*/
|
||||
bool config_have_required_ssl_params(CONFIG_CONTEXT *obj);
|
||||
|
||||
/**
|
||||
* @brief Helper function for checking SSL parameters
|
||||
*
|
||||
* @param key Parameter name
|
||||
* @return True if the parameter is an SSL parameter
|
||||
*/
|
||||
bool config_is_ssl_parameter(const char *key);
|
||||
|
||||
/**
|
||||
* @brief Construct an SSL structure
|
||||
*
|
||||
* The SSL structure is used by both listeners and servers.
|
||||
*
|
||||
* TODO: Rename to something like @c config_construct_ssl
|
||||
*
|
||||
* @param obj Configuration context
|
||||
* @param require_cert Whether certificates are required
|
||||
* @param error_count Pointer to an int which is incremented for each error
|
||||
* @return New SSL_LISTENER structure or NULL on error
|
||||
*/
|
||||
SSL_LISTENER *make_ssl_structure(CONFIG_CONTEXT *obj, bool require_cert, int *error_count);
|
||||
|
||||
char* config_clean_string_list(const char* str);
|
||||
CONFIG_PARAMETER* config_clone_param(const CONFIG_PARAMETER* param);
|
||||
void config_enable_feedback_task(void);
|
||||
void config_disable_feedback_task(void);
|
||||
unsigned long config_get_gateway_id(void);
|
||||
GATEWAY_CONF* config_get_global_options();
|
||||
CONFIG_PARAMETER* config_get_param(CONFIG_PARAMETER* params, const char* name);
|
||||
config_param_type_t config_get_paramtype(const CONFIG_PARAMETER* param);
|
||||
bool config_get_valint(int* val,
|
||||
const CONFIG_PARAMETER* param,
|
||||
|
@ -280,7 +280,5 @@ extern void server_update_port(SERVER *, unsigned short);
|
||||
extern RESULTSET *serverGetList();
|
||||
extern unsigned int server_map_status(char *str);
|
||||
extern bool server_set_version_string(SERVER* server, const char* string);
|
||||
extern bool server_is_ssl_parameter(const char *key);
|
||||
extern void server_update_ssl(SERVER *server, const char *key, const char *value);
|
||||
|
||||
MXS_END_DECLS
|
||||
|
@ -80,7 +80,6 @@ static void duplicate_context_finish(DUPLICATE_CONTEXT* context);
|
||||
extern int setipaddress(struct in_addr *, char *);
|
||||
static bool process_config_context(CONFIG_CONTEXT *);
|
||||
static bool process_config_update(CONFIG_CONTEXT *);
|
||||
static void free_config_context(CONFIG_CONTEXT *);
|
||||
static char *config_get_value(CONFIG_PARAMETER *, const char *);
|
||||
static char *config_get_password(CONFIG_PARAMETER *);
|
||||
static const char *config_get_value_string(CONFIG_PARAMETER *, const char *);
|
||||
@ -90,13 +89,11 @@ static void global_defaults();
|
||||
static void feedback_defaults();
|
||||
static bool check_config_objects(CONFIG_CONTEXT *context);
|
||||
static int maxscale_getline(char** dest, int* size, FILE* file);
|
||||
static SSL_LISTENER *make_ssl_structure(CONFIG_CONTEXT *obj, bool require_cert, int *error_count);
|
||||
|
||||
int config_truth_value(char *str);
|
||||
int config_get_ifaddr(unsigned char *output);
|
||||
static int config_get_release_string(char* release);
|
||||
FEEDBACK_CONF *config_get_feedback_data();
|
||||
void config_add_param(CONFIG_CONTEXT*, char*, char*);
|
||||
bool config_has_duplicate_sections(const char* config, DUPLICATE_CONTEXT* context);
|
||||
int create_new_service(CONFIG_CONTEXT *obj);
|
||||
int create_new_server(CONFIG_CONTEXT *obj);
|
||||
@ -326,6 +323,20 @@ char* config_clean_string_list(const char* str)
|
||||
return dest;
|
||||
}
|
||||
|
||||
CONFIG_CONTEXT* config_context_create(const char *section)
|
||||
{
|
||||
CONFIG_CONTEXT* ctx = (CONFIG_CONTEXT *)MXS_MALLOC(sizeof(CONFIG_CONTEXT));
|
||||
if (ctx)
|
||||
{
|
||||
ctx->object = MXS_STRDUP_A(section);
|
||||
ctx->parameters = NULL;
|
||||
ctx->next = NULL;
|
||||
ctx->element = NULL;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Config item handler for the ini file reader
|
||||
*
|
||||
@ -340,7 +351,6 @@ ini_handler(void *userdata, const char *section, const char *name, const char *v
|
||||
{
|
||||
CONFIG_CONTEXT *cntxt = (CONFIG_CONTEXT *)userdata;
|
||||
CONFIG_CONTEXT *ptr = cntxt;
|
||||
CONFIG_PARAMETER *param, *p1;
|
||||
|
||||
if (strcmp(section, "gateway") == 0 || strcasecmp(section, "MaxScale") == 0)
|
||||
{
|
||||
@ -368,54 +378,24 @@ ini_handler(void *userdata, const char *section, const char *name, const char *v
|
||||
|
||||
if (!ptr)
|
||||
{
|
||||
if ((ptr = (CONFIG_CONTEXT *)MXS_MALLOC(sizeof(CONFIG_CONTEXT))) == NULL)
|
||||
if ((ptr = config_context_create(section)) == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ptr->object = MXS_STRDUP_A(section);
|
||||
ptr->parameters = NULL;
|
||||
ptr->next = cntxt->next;
|
||||
ptr->element = NULL;
|
||||
cntxt->next = ptr;
|
||||
}
|
||||
/* Check to see if the parameter already exists for the section */
|
||||
p1 = ptr->parameters;
|
||||
while (p1)
|
||||
{
|
||||
if (!strcmp(p1->name, name))
|
||||
{
|
||||
char *tmp;
|
||||
int paramlen = strlen(p1->value) + strlen(value) + 2;
|
||||
|
||||
if ((tmp = MXS_REALLOC(p1->value, sizeof(char) * (paramlen))) == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
strcat(tmp, ",");
|
||||
strcat(tmp, value);
|
||||
if ((p1->value = config_clean_string_list(tmp)) == NULL)
|
||||
{
|
||||
p1->value = tmp;
|
||||
MXS_ERROR("[%s] Cleaning configuration parameter failed.", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
MXS_FREE(tmp);
|
||||
return 1;
|
||||
}
|
||||
p1 = p1->next;
|
||||
}
|
||||
|
||||
if ((param = (CONFIG_PARAMETER *)MXS_MALLOC(sizeof(CONFIG_PARAMETER))) == NULL)
|
||||
if (config_get_param(ptr->parameters, name) &&
|
||||
!config_append_param(ptr, name, value))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (!config_add_param(ptr, name, value))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
param->name = MXS_STRDUP_A(name);
|
||||
param->value = MXS_STRDUP_A(value);
|
||||
param->next = ptr->parameters;
|
||||
param->qfd_param_type = UNDEFINED_TYPE;
|
||||
ptr->parameters = param;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -637,7 +617,7 @@ config_load_and_process(const char* filename, bool (*process_config)(CONFIG_CONT
|
||||
}
|
||||
}
|
||||
|
||||
free_config_context(ccontext.next);
|
||||
config_context_free(ccontext.next);
|
||||
|
||||
duplicate_context_finish(&dcontext);
|
||||
}
|
||||
@ -876,10 +856,7 @@ config_get_value_string(CONFIG_PARAMETER *params, const char *name)
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
CONFIG_PARAMETER* config_get_param(
|
||||
CONFIG_PARAMETER* params,
|
||||
const char* name)
|
||||
CONFIG_PARAMETER* config_get_param(CONFIG_PARAMETER* params, const char* name)
|
||||
{
|
||||
while (params)
|
||||
{
|
||||
@ -1042,22 +1019,15 @@ void free_config_parameter(CONFIG_PARAMETER* p1)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a config tree
|
||||
*
|
||||
* @param context The configuration data
|
||||
*/
|
||||
static void
|
||||
free_config_context(CONFIG_CONTEXT *context)
|
||||
void config_context_free(CONFIG_CONTEXT *context)
|
||||
{
|
||||
CONFIG_CONTEXT *obj;
|
||||
CONFIG_PARAMETER *p1, *p2;
|
||||
|
||||
while (context)
|
||||
{
|
||||
MXS_FREE(context->object);
|
||||
free_config_parameter(context->parameters);
|
||||
obj = context->next;
|
||||
free_config_parameter(context->parameters);
|
||||
MXS_FREE(context->object);
|
||||
MXS_FREE(context);
|
||||
context = obj;
|
||||
}
|
||||
@ -1362,8 +1332,7 @@ free_ssl_structure(SSL_LISTENER *ssl)
|
||||
* @param *error_count An error count which may be incremented
|
||||
* @return SSL_LISTENER structure or NULL
|
||||
*/
|
||||
static SSL_LISTENER *
|
||||
make_ssl_structure (CONFIG_CONTEXT *obj, bool require_cert, int *error_count)
|
||||
SSL_LISTENER* make_ssl_structure (CONFIG_CONTEXT *obj, bool require_cert, int *error_count)
|
||||
{
|
||||
char *ssl, *ssl_version, *ssl_cert, *ssl_key, *ssl_ca_cert, *ssl_cert_verify_depth;
|
||||
int local_errors = 0;
|
||||
@ -2288,26 +2257,57 @@ unsigned long config_get_gateway_id()
|
||||
return gateway.id;
|
||||
}
|
||||
|
||||
void config_add_param(CONFIG_CONTEXT* obj, char* key, char* value)
|
||||
bool config_add_param(CONFIG_CONTEXT* obj, const char* key, const char* value)
|
||||
{
|
||||
key = MXS_STRDUP(key);
|
||||
value = MXS_STRDUP(value);
|
||||
ss_dassert(config_get_param(obj->parameters, key) == NULL);
|
||||
bool rval = false;
|
||||
char *my_key = MXS_STRDUP(key);
|
||||
char *my_value = MXS_STRDUP(value);
|
||||
CONFIG_PARAMETER* param = (CONFIG_PARAMETER *)MXS_MALLOC(sizeof(*param));
|
||||
|
||||
CONFIG_PARAMETER* param = (CONFIG_PARAMETER *)MXS_MALLOC(sizeof(CONFIG_PARAMETER));
|
||||
|
||||
if (!key || !value || !param)
|
||||
if (my_key && my_value && param)
|
||||
{
|
||||
MXS_FREE(key);
|
||||
MXS_FREE(value);
|
||||
param->name = my_key;
|
||||
param->value = my_value;
|
||||
param->qfd_param_type = UNDEFINED_TYPE;
|
||||
param->next = obj->parameters;
|
||||
obj->parameters = param;
|
||||
rval = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_FREE(my_key);
|
||||
MXS_FREE(my_value);
|
||||
MXS_FREE(param);
|
||||
return;
|
||||
}
|
||||
|
||||
param->name = key;
|
||||
param->value = value;
|
||||
param->next = obj->parameters;
|
||||
obj->parameters = param;
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool config_append_param(CONFIG_CONTEXT* obj, const char* key, const char* value)
|
||||
{
|
||||
CONFIG_PARAMETER *param = config_get_param(obj->parameters, key);
|
||||
ss_dassert(param);
|
||||
int paramlen = strlen(param->value) + strlen(value) + 2;
|
||||
char tmp[paramlen];
|
||||
bool rval = false;
|
||||
|
||||
strcpy(tmp, param->value);
|
||||
strcat(tmp, ",");
|
||||
strcat(tmp, value);
|
||||
|
||||
char *new_value = config_clean_string_list(tmp);
|
||||
|
||||
if (new_value)
|
||||
{
|
||||
MXS_FREE(param->value);
|
||||
param->value = new_value;
|
||||
rval = true;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the pointer to the global options for MaxScale.
|
||||
* @return Pointer to the GATEWAY_CONF structure. This is a static structure and
|
||||
@ -3158,3 +3158,38 @@ int create_new_filter(CONFIG_CONTEXT *obj)
|
||||
|
||||
return error_count;
|
||||
}
|
||||
|
||||
bool config_have_required_ssl_params(CONFIG_CONTEXT *obj)
|
||||
{
|
||||
CONFIG_PARAMETER *param = obj->parameters;
|
||||
|
||||
return config_get_param(param, "ssl") &&
|
||||
config_get_param(param, "ssl_key") &&
|
||||
config_get_param(param, "ssl_cert") &&
|
||||
config_get_param(param, "ssl_ca_cert") &&
|
||||
strcmp(config_get_value_string(param, "ssl"), "required") == 0;
|
||||
}
|
||||
|
||||
bool config_is_ssl_parameter(const char *key)
|
||||
{
|
||||
const char *ssl_params[] =
|
||||
{
|
||||
"ssl_cert",
|
||||
"ssl_ca_cert",
|
||||
"ssl",
|
||||
"ssl_key",
|
||||
"ssl_version",
|
||||
"ssl_cert_verify_depth",
|
||||
NULL
|
||||
};
|
||||
|
||||
for (int i = 0; ssl_params[i]; i++)
|
||||
{
|
||||
if (strcmp(key, ssl_params[i]) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1354,14 +1354,3 @@ bool server_destroy(SERVER *server)
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool server_is_ssl_parameter(const char *key)
|
||||
{
|
||||
// TODO: Implement this
|
||||
return false;
|
||||
}
|
||||
|
||||
void server_update_ssl(SERVER *server, const char *key, const char *value)
|
||||
{
|
||||
// TODO: Implement this
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user