Reindent server/core/service.c
This commit is contained in:
@ -27,7 +27,8 @@
|
||||
* 24/06/13 Massimiliano Pinto Added: Loading users from mysql backend in serviceStart
|
||||
* 06/02/14 Massimiliano Pinto Added: serviceEnableRootUser routine
|
||||
* 25/02/14 Massimiliano Pinto Added: service refresh limit feature
|
||||
* 28/02/14 Massimiliano Pinto users_alloc moved from service_alloc to serviceStartPort (generic hashable for services)
|
||||
* 28/02/14 Massimiliano Pinto users_alloc moved from service_alloc to
|
||||
* serviceStartPort (generic hashable for services)
|
||||
* 07/05/14 Massimiliano Pinto Added: version_string initialized to NULL
|
||||
* 23/05/14 Mark Riddoch Addition of service validation call
|
||||
* 29/05/14 Mark Riddoch Filter API implementation
|
||||
@ -70,18 +71,21 @@ static RSA *rsa_512 = NULL;
|
||||
static RSA *rsa_1024 = NULL;
|
||||
|
||||
/** To be used with configuration type checks */
|
||||
typedef struct typelib_st {
|
||||
typedef struct typelib_st
|
||||
{
|
||||
int tl_nelems;
|
||||
const char* tl_name;
|
||||
const char** tl_p_elems;
|
||||
} typelib_t;
|
||||
|
||||
/** Set of subsequent false,true pairs */
|
||||
static const char* bool_strings[11] = {"FALSE", "TRUE", "OFF", "ON", "N", "Y", "0", "1", "NO", "YES", 0};
|
||||
typelib_t bool_type = {array_nelems(bool_strings)-1, "bool_type", bool_strings};
|
||||
|
||||
/** List of valid values */
|
||||
static const char* sqlvar_target_strings[4] = {"MASTER", "ALL", 0};
|
||||
typelib_t sqlvar_target_type = {
|
||||
typelib_t sqlvar_target_type =
|
||||
{
|
||||
array_nelems(sqlvar_target_strings) - 1,
|
||||
"sqlvar_target_type",
|
||||
sqlvar_target_strings
|
||||
@ -92,8 +96,7 @@ static SERVICE *allServices = NULL;
|
||||
|
||||
static int find_type(typelib_t* tl, const char* needle, int maxlen);
|
||||
|
||||
static void service_add_qualified_param(
|
||||
SERVICE* svc,
|
||||
static void service_add_qualified_param(SERVICE* svc,
|
||||
CONFIG_PARAMETER* param);
|
||||
void service_interal_restart(void *data);
|
||||
|
||||
@ -112,7 +115,9 @@ service_alloc(const char *servname, const char *router)
|
||||
SERVICE *service;
|
||||
|
||||
if ((service = (SERVICE *)calloc(1, sizeof(SERVICE))) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if ((service->router = load_module(router, MODULE_ROUTER)) == NULL)
|
||||
{
|
||||
char* home = get_libdir();
|
||||
@ -149,7 +154,9 @@ SERVICE *service;
|
||||
if (service->name == NULL || service->routerModule == NULL)
|
||||
{
|
||||
if (service->name)
|
||||
{
|
||||
free(service->name);
|
||||
}
|
||||
free(service);
|
||||
return NULL;
|
||||
}
|
||||
@ -216,10 +223,12 @@ GWPROTOCOL *funcs;
|
||||
goto retblock;
|
||||
}
|
||||
|
||||
if (strcmp(port->protocol, "MySQLClient") == 0) {
|
||||
if (strcmp(port->protocol, "MySQLClient") == 0)
|
||||
{
|
||||
int loaded;
|
||||
|
||||
if (service->users == NULL) {
|
||||
if (service->users == NULL)
|
||||
{
|
||||
/*
|
||||
* Allocate specific data for MySQL users
|
||||
* including hosts and db names
|
||||
@ -323,14 +332,14 @@ GWPROTOCOL *funcs;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (service->users == NULL) {
|
||||
if (service->users == NULL)
|
||||
{
|
||||
/* Generic users table */
|
||||
service->users = users_alloc();
|
||||
}
|
||||
}
|
||||
|
||||
if ((funcs=(GWPROTOCOL *)load_module(port->protocol, MODULE_PROTOCOL))
|
||||
== NULL)
|
||||
if ((funcs=(GWPROTOCOL *)load_module(port->protocol, MODULE_PROTOCOL)) == NULL)
|
||||
{
|
||||
users_free(service->users);
|
||||
service->users = NULL;
|
||||
@ -346,9 +355,13 @@ GWPROTOCOL *funcs;
|
||||
memcpy(&(port->listener->func), funcs, sizeof(GWPROTOCOL));
|
||||
|
||||
if (port->address)
|
||||
{
|
||||
sprintf(config_bind, "%s:%d", port->address, port->port);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(config_bind, "0.0.0.0:%d", port->port);
|
||||
}
|
||||
|
||||
if (port->listener->func.listen(port->listener, config_bind))
|
||||
{
|
||||
@ -448,7 +461,6 @@ serviceStart(SERVICE *service)
|
||||
{
|
||||
int listeners = 0;
|
||||
|
||||
|
||||
if (check_service_permissions(service))
|
||||
{
|
||||
if (service->ssl_mode == SSL_DISABLED ||
|
||||
@ -497,7 +509,9 @@ SERV_PROTOCOL *ptr;
|
||||
while (ptr)
|
||||
{
|
||||
if (strcmp(ptr->protocol, protocol) == 0 && ptr->port == port)
|
||||
{
|
||||
serviceStartPort(service, ptr);
|
||||
}
|
||||
ptr = ptr->next;
|
||||
}
|
||||
}
|
||||
@ -548,8 +562,7 @@ int listeners = 0;
|
||||
port = service->ports;
|
||||
while (port)
|
||||
{
|
||||
if(port->listener &&
|
||||
port->listener->session->state == SESSION_STATE_LISTENER)
|
||||
if (port->listener && port->listener->session->state == SESSION_STATE_LISTENER)
|
||||
{
|
||||
if (poll_remove_dcb(port->listener) == 0)
|
||||
{
|
||||
@ -581,8 +594,7 @@ int listeners = 0;
|
||||
port = service->ports;
|
||||
while (port)
|
||||
{
|
||||
if(port->listener &&
|
||||
port->listener->session->state == SESSION_STATE_LISTENER_STOPPED)
|
||||
if (port->listener && port->listener->session->state == SESSION_STATE_LISTENER_STOPPED)
|
||||
{
|
||||
if (poll_add_dcb(port->listener) == 0)
|
||||
{
|
||||
@ -609,7 +621,9 @@ service_free(SERVICE *service)
|
||||
SERVICE *ptr;
|
||||
SERVER_REF *srv;
|
||||
if (service->stats.n_current)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* First of all remove from the linked list */
|
||||
spinlock_acquire(&service_spin);
|
||||
if (allServices == service)
|
||||
@ -624,13 +638,15 @@ SERVER_REF *srv;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
if (ptr)
|
||||
{
|
||||
ptr->next = service->next;
|
||||
}
|
||||
}
|
||||
spinlock_release(&service_spin);
|
||||
|
||||
/* Clean up session and free the memory */
|
||||
|
||||
while(service->dbref){
|
||||
while (service->dbref)
|
||||
{
|
||||
srv = service->dbref;
|
||||
service->dbref = service->dbref->next;
|
||||
free(srv);
|
||||
@ -639,9 +655,13 @@ SERVER_REF *srv;
|
||||
free(service->name);
|
||||
free(service->routerModule);
|
||||
if (service->credentials.name)
|
||||
{
|
||||
free(service->credentials.name);
|
||||
}
|
||||
if (service->credentials.authdata)
|
||||
{
|
||||
free(service->credentials.authdata);
|
||||
}
|
||||
free(service);
|
||||
return 1;
|
||||
}
|
||||
@ -667,9 +687,13 @@ SERV_PROTOCOL *proto;
|
||||
proto->listener = NULL;
|
||||
proto->protocol = strdup(protocol);
|
||||
if (address)
|
||||
{
|
||||
proto->address = strdup(address);
|
||||
}
|
||||
else
|
||||
{
|
||||
proto->address = NULL;
|
||||
}
|
||||
proto->port = port;
|
||||
spinlock_acquire(&service->spin);
|
||||
proto->next = service->ports;
|
||||
@ -697,7 +721,9 @@ SERV_PROTOCOL *proto;
|
||||
while (proto)
|
||||
{
|
||||
if (strcmp(proto->protocol, protocol) == 0 && proto->port == port)
|
||||
{
|
||||
break;
|
||||
}
|
||||
proto = proto->next;
|
||||
}
|
||||
spinlock_release(&service->spin);
|
||||
@ -740,7 +766,9 @@ SERVER_REF *ptr;
|
||||
spinlock_acquire(&service->spin);
|
||||
ptr = service->dbref;
|
||||
while (ptr && ptr->server != server)
|
||||
{
|
||||
ptr = ptr->next;
|
||||
}
|
||||
spinlock_release(&service->spin);
|
||||
|
||||
return ptr != NULL;
|
||||
@ -767,7 +795,9 @@ int i;
|
||||
else
|
||||
{
|
||||
for (i = 0; service->routerOptions[i]; i++)
|
||||
{
|
||||
;
|
||||
}
|
||||
service->routerOptions = (char **)realloc(service->routerOptions,
|
||||
(i + 2) * sizeof(char *));
|
||||
service->routerOptions[i] = strdup(option);
|
||||
@ -790,7 +820,9 @@ int i;
|
||||
if (service->routerOptions != NULL)
|
||||
{
|
||||
for (i = 0; service->routerOptions[i]; i++)
|
||||
{
|
||||
free(service->routerOptions[i]);
|
||||
}
|
||||
free(service->routerOptions);
|
||||
service->routerOptions = NULL;
|
||||
}
|
||||
@ -809,14 +841,20 @@ int
|
||||
serviceSetUser(SERVICE *service, char *user, char *auth)
|
||||
{
|
||||
if (service->credentials.name)
|
||||
{
|
||||
free(service->credentials.name);
|
||||
}
|
||||
if (service->credentials.authdata)
|
||||
{
|
||||
free(service->credentials.authdata);
|
||||
}
|
||||
service->credentials.name = strdup(user);
|
||||
service->credentials.authdata = strdup(auth);
|
||||
|
||||
if (service->credentials.name == NULL || service->credentials.authdata == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -834,7 +872,9 @@ int
|
||||
serviceGetUser(SERVICE *service, char **user, char **auth)
|
||||
{
|
||||
if (service->credentials.name == NULL || service->credentials.authdata == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
*user = service->credentials.name;
|
||||
*auth = service->credentials.authdata;
|
||||
return 1;
|
||||
@ -853,7 +893,9 @@ int
|
||||
serviceEnableRootUser(SERVICE *service, int action)
|
||||
{
|
||||
if (action != 0 && action != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
service->enable_root = action;
|
||||
|
||||
@ -872,7 +914,9 @@ int
|
||||
serviceAuthAllServers(SERVICE *service, int action)
|
||||
{
|
||||
if (action != 0 && action != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
service->users_from_all = action;
|
||||
|
||||
@ -891,7 +935,9 @@ int
|
||||
serviceOptimizeWildcard(SERVICE *service, int action)
|
||||
{
|
||||
if (action != 0 && action != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
service->optimize_wildcard = action;
|
||||
if (action)
|
||||
@ -913,15 +959,21 @@ void
|
||||
serviceSetCertificates(SERVICE *service, char* cert,char* key, char* ca_cert)
|
||||
{
|
||||
if (service->ssl_cert)
|
||||
{
|
||||
free(service->ssl_cert);
|
||||
}
|
||||
service->ssl_cert = strdup(cert);
|
||||
|
||||
if (service->ssl_key)
|
||||
{
|
||||
free(service->ssl_key);
|
||||
}
|
||||
service->ssl_key = strdup(key);
|
||||
|
||||
if (service->ssl_ca_cert)
|
||||
{
|
||||
free(service->ssl_ca_cert);
|
||||
}
|
||||
service->ssl_ca_cert = strdup(ca_cert);
|
||||
}
|
||||
|
||||
@ -935,18 +987,31 @@ int
|
||||
serviceSetSSLVersion(SERVICE *service, char* version)
|
||||
{
|
||||
if (strcasecmp(version,"SSLV3") == 0)
|
||||
{
|
||||
service->ssl_method_type = SERVICE_SSLV3;
|
||||
}
|
||||
else if (strcasecmp(version,"TLSV10") == 0)
|
||||
{
|
||||
service->ssl_method_type = SERVICE_TLS10;
|
||||
}
|
||||
#ifdef OPENSSL_1_0
|
||||
else if (strcasecmp(version,"TLSV11") == 0)
|
||||
{
|
||||
service->ssl_method_type = SERVICE_TLS11;
|
||||
}
|
||||
else if (strcasecmp(version,"TLSV12") == 0)
|
||||
{
|
||||
service->ssl_method_type = SERVICE_TLS12;
|
||||
}
|
||||
#endif
|
||||
else if (strcasecmp(version,"MAX") == 0)
|
||||
{
|
||||
service->ssl_method_type = SERVICE_SSL_TLS_MAX;
|
||||
else return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -960,7 +1025,9 @@ serviceSetSSLVersion(SERVICE *service, char* version)
|
||||
int serviceSetSSLVerifyDepth(SERVICE* service, int depth)
|
||||
{
|
||||
if (depth < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
service->ssl_cert_verify_depth = depth;
|
||||
return 0;
|
||||
@ -983,13 +1050,21 @@ serviceSetSSL(SERVICE *service, char* action)
|
||||
int rval = 0;
|
||||
|
||||
if (strcasecmp(action,"required") == 0)
|
||||
{
|
||||
service->ssl_mode = SSL_REQUIRED;
|
||||
}
|
||||
else if (strcasecmp(action,"enabled") == 0)
|
||||
{
|
||||
service->ssl_mode = SSL_ENABLED;
|
||||
}
|
||||
else if (strcasecmp(action,"disabled") == 0)
|
||||
{
|
||||
service->ssl_mode = SSL_DISABLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
rval = -1;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
@ -1004,7 +1079,9 @@ serviceSetSSL(SERVICE *service, char* action)
|
||||
int serviceStripDbEsc(SERVICE* service, int action)
|
||||
{
|
||||
if (action != 0 && action != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
service->strip_db_esc = action;
|
||||
|
||||
@ -1023,7 +1100,9 @@ serviceSetTimeout(SERVICE *service, int val)
|
||||
{
|
||||
|
||||
if (val < 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
service->conn_timeout = val;
|
||||
|
||||
return 1;
|
||||
@ -1054,12 +1133,16 @@ trim(char *str)
|
||||
char *ptr;
|
||||
|
||||
while (isspace(*str))
|
||||
{
|
||||
str++;
|
||||
}
|
||||
|
||||
/* Point to last character of the string */
|
||||
ptr = str + strlen(str) - 1;
|
||||
while (ptr > str && isspace(*ptr))
|
||||
{
|
||||
*ptr-- = 0;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
@ -1150,7 +1233,9 @@ SERVICE *service;
|
||||
spinlock_acquire(&service_spin);
|
||||
service = allServices;
|
||||
while (service && strcmp(service->name, servname) != 0)
|
||||
{
|
||||
service = service->next;
|
||||
}
|
||||
spinlock_release(&service_spin);
|
||||
|
||||
return service;
|
||||
@ -1172,7 +1257,8 @@ int i;
|
||||
|
||||
printf("Service %p\n", (void *)service);
|
||||
printf("\tService: %s\n", service->name);
|
||||
printf("\tRouter: %s (%p)\n", service->routerModule, (void *)service->router);
|
||||
printf("\tRouter: %s (%p)\n",
|
||||
service->routerModule, (void *)service->router);
|
||||
printf("\tStarted: %s",
|
||||
asctime_r(localtime_r(&service->stats.started, &result), time_buf));
|
||||
printf("\tBackend databases\n");
|
||||
@ -1297,8 +1383,10 @@ int i;
|
||||
server = server->next;
|
||||
}
|
||||
if (service->weightby)
|
||||
{
|
||||
dcb_printf(dcb, "\tRouting weight parameter: %s\n",
|
||||
service->weightby);
|
||||
}
|
||||
dcb_printf(dcb, "\tUsers data: %p\n",
|
||||
service->users);
|
||||
dcb_printf(dcb, "\tTotal connections: %d\n",
|
||||
@ -1338,7 +1426,9 @@ SERVICE *service;
|
||||
service = service->next;
|
||||
}
|
||||
if (allServices)
|
||||
{
|
||||
dcb_printf(dcb, "--------------------------+----------------------+--------+---------------\n\n");
|
||||
}
|
||||
spinlock_release(&service_spin);
|
||||
}
|
||||
|
||||
@ -1375,15 +1465,16 @@ SERV_PROTOCOL *lptr;
|
||||
(!lptr->listener ||
|
||||
!lptr->listener->session ||
|
||||
lptr->listener->session->state == SESSION_STATE_LISTENER_STOPPED) ?
|
||||
"Stopped" : "Running"
|
||||
);
|
||||
"Stopped" : "Running");
|
||||
|
||||
lptr = lptr->next;
|
||||
}
|
||||
service = service->next;
|
||||
}
|
||||
if (allServices)
|
||||
{
|
||||
dcb_printf(dcb, "---------------------+--------------------+-----------------+-------+--------\n\n");
|
||||
}
|
||||
spinlock_release(&service_spin);
|
||||
}
|
||||
|
||||
@ -1436,10 +1527,12 @@ void *router_obj;
|
||||
* @param service Service to reload
|
||||
* @return 0 on success and 1 on error
|
||||
*/
|
||||
int service_refresh_users(SERVICE *service) {
|
||||
int service_refresh_users(SERVICE *service)
|
||||
{
|
||||
int ret = 1;
|
||||
/* check for another running getUsers request */
|
||||
if (! spinlock_acquire_nowait(&service->users_table_spin)) {
|
||||
if (!spinlock_acquire_nowait(&service->users_table_spin))
|
||||
{
|
||||
MXS_DEBUG("%s: [service_refresh_users] failed to get get lock for "
|
||||
"loading new users' table: another thread is loading users",
|
||||
service->name);
|
||||
@ -1447,9 +1540,10 @@ int service_refresh_users(SERVICE *service) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* check if refresh rate limit has exceeded */
|
||||
if ( (time(NULL) < (service->rate_limit.last + USERS_REFRESH_TIME)) || (service->rate_limit.nloads > USERS_REFRESH_MAX_PER_TIME)) {
|
||||
if ((time(NULL) < (service->rate_limit.last + USERS_REFRESH_TIME)) ||
|
||||
(service->rate_limit.nloads > USERS_REFRESH_MAX_PER_TIME))
|
||||
{
|
||||
spinlock_release(&service->users_table_spin);
|
||||
MXS_ERROR("%s: Refresh rate limit exceeded for load of users' table.",
|
||||
service->name);
|
||||
@ -1460,7 +1554,8 @@ int service_refresh_users(SERVICE *service) {
|
||||
service->rate_limit.nloads++;
|
||||
|
||||
/* update time and counter */
|
||||
if (service->rate_limit.nloads > USERS_REFRESH_MAX_PER_TIME) {
|
||||
if (service->rate_limit.nloads > USERS_REFRESH_MAX_PER_TIME)
|
||||
{
|
||||
service->rate_limit.nloads = 1;
|
||||
service->rate_limit.last = time(NULL);
|
||||
}
|
||||
@ -1471,13 +1566,16 @@ int service_refresh_users(SERVICE *service) {
|
||||
spinlock_release(&service->users_table_spin);
|
||||
|
||||
if (ret >= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool service_set_param_value (
|
||||
SERVICE* service,
|
||||
bool service_set_param_value(SERVICE* service,
|
||||
CONFIG_PARAMETER* param,
|
||||
char* valstr,
|
||||
count_spec_t count_spec,
|
||||
@ -1496,7 +1594,10 @@ bool service_set_param_value (
|
||||
*/
|
||||
p = valstr;
|
||||
|
||||
while(isdigit(*p)) p++;
|
||||
while (isdigit(*p))
|
||||
{
|
||||
p++;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
|
||||
@ -1567,9 +1668,7 @@ bool service_set_param_value (
|
||||
valbool = true;
|
||||
}
|
||||
/** add param to config */
|
||||
config_set_qualified_param(param,
|
||||
(void *)&valbool,
|
||||
BOOL_TYPE);
|
||||
config_set_qualified_param(param, (void *)&valbool, BOOL_TYPE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1594,9 +1693,7 @@ bool service_set_param_value (
|
||||
valtarget = TYPE_ALL;
|
||||
}
|
||||
/** add param to config */
|
||||
config_set_qualified_param(param,
|
||||
(void *)&valtarget,
|
||||
SQLVAR_TARGET_TYPE);
|
||||
config_set_qualified_param(param, (void *)&valtarget, SQLVAR_TARGET_TYPE);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1625,8 +1722,7 @@ bool service_set_param_value (
|
||||
* 0 error
|
||||
* > 0 position in TYPELIB->type_names +1
|
||||
*/
|
||||
static int find_type(
|
||||
typelib_t* tl,
|
||||
static int find_type(typelib_t* tl,
|
||||
const char* needle,
|
||||
int maxlen)
|
||||
{
|
||||
@ -1650,8 +1746,7 @@ static int find_type(
|
||||
/**
|
||||
* Add qualified config parameter to SERVICE struct.
|
||||
*/
|
||||
static void service_add_qualified_param(
|
||||
SERVICE* svc,
|
||||
static void service_add_qualified_param(SERVICE* svc,
|
||||
CONFIG_PARAMETER* param)
|
||||
{
|
||||
spinlock_acquire(&svc->spin);
|
||||
@ -1729,7 +1824,9 @@ void
|
||||
serviceWeightBy(SERVICE *service, char *weightby)
|
||||
{
|
||||
if (service->weightby)
|
||||
{
|
||||
free(service->weightby);
|
||||
}
|
||||
service->weightby = strdup(weightby);
|
||||
}
|
||||
|
||||
@ -1757,7 +1854,9 @@ int
|
||||
serviceEnableLocalhostMatchWildcardHost(SERVICE *service, int action)
|
||||
{
|
||||
if (action != 0 && action != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
service->localhost_match_wildcard_host = action;
|
||||
|
||||
@ -1820,22 +1919,28 @@ SERV_PROTOCOL *lptr = NULL;
|
||||
spinlock_acquire(&service_spin);
|
||||
service = allServices;
|
||||
if (service)
|
||||
{
|
||||
lptr = service->ports;
|
||||
}
|
||||
while (i < *rowno && service)
|
||||
{
|
||||
lptr = service->ports;
|
||||
while (i < *rowno && lptr)
|
||||
{
|
||||
if ((lptr = lptr->next) != NULL)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (i < *rowno)
|
||||
{
|
||||
service = service->next;
|
||||
if (service && (lptr = service->ports) != NULL)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lptr == NULL)
|
||||
{
|
||||
spinlock_release(&service_spin);
|
||||
@ -1869,7 +1974,9 @@ RESULTSET *set;
|
||||
int *data;
|
||||
|
||||
if ((data = (int *)malloc(sizeof(int))) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
*data = 0;
|
||||
if ((set = resultset_create(serviceListenerRowCallback, data)) == NULL)
|
||||
{
|
||||
@ -1896,7 +2003,7 @@ static RESULT_ROW *
|
||||
serviceRowCallback(RESULTSET *set, void *data)
|
||||
{
|
||||
int *rowno = (int *)data;
|
||||
int i = 0;;
|
||||
int i = 0;
|
||||
char buf[20];
|
||||
RESULT_ROW *row;
|
||||
SERVICE *service;
|
||||
@ -1938,7 +2045,9 @@ RESULTSET *set;
|
||||
int *data;
|
||||
|
||||
if ((data = (int *)malloc(sizeof(int))) == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
*data = 0;
|
||||
if ((set = resultset_create(serviceRowCallback, data)) == NULL)
|
||||
{
|
||||
@ -1968,23 +2077,33 @@ int *data;
|
||||
switch (keylength) {
|
||||
case 512:
|
||||
if (rsa_512)
|
||||
{
|
||||
rsa_tmp = rsa_512;
|
||||
else { /* generate on the fly, should not happen in this example */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* generate on the fly, should not happen in this example */
|
||||
rsa_tmp = RSA_generate_key(keylength,RSA_F4,NULL,NULL);
|
||||
rsa_512 = rsa_tmp; /* Remember for later reuse */
|
||||
}
|
||||
break;
|
||||
case 1024:
|
||||
if (rsa_1024)
|
||||
{
|
||||
rsa_tmp=rsa_1024;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Generating a key on the fly is very costly, so use what is there */
|
||||
if (rsa_1024)
|
||||
{
|
||||
rsa_tmp=rsa_1024;
|
||||
}
|
||||
else
|
||||
{
|
||||
rsa_tmp=rsa_512; /* Use at least a shorter key */
|
||||
}
|
||||
}
|
||||
return(rsa_tmp);
|
||||
}
|
||||
|
||||
@ -2063,29 +2182,34 @@ int serviceInitSSL(SERVICE* service)
|
||||
}
|
||||
|
||||
if (rsa_512 != NULL && rsa_1024 != NULL)
|
||||
{
|
||||
SSL_CTX_set_tmp_rsa_callback(service->ctx,tmp_rsa_callback);
|
||||
}
|
||||
|
||||
/** Load the server sertificate */
|
||||
if (SSL_CTX_use_certificate_file(service->ctx, service->ssl_cert, SSL_FILETYPE_PEM) <= 0) {
|
||||
if (SSL_CTX_use_certificate_file(service->ctx, service->ssl_cert, SSL_FILETYPE_PEM) <= 0)
|
||||
{
|
||||
MXS_ERROR("Failed to set server SSL certificate.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Load the private-key corresponding to the server certificate */
|
||||
if (SSL_CTX_use_PrivateKey_file(service->ctx, service->ssl_key, SSL_FILETYPE_PEM) <= 0) {
|
||||
if (SSL_CTX_use_PrivateKey_file(service->ctx, service->ssl_key, SSL_FILETYPE_PEM) <= 0)
|
||||
{
|
||||
MXS_ERROR("Failed to set server SSL key.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check if the server certificate and private-key matches */
|
||||
if (!SSL_CTX_check_private_key(service->ctx)) {
|
||||
if (!SSL_CTX_check_private_key(service->ctx))
|
||||
{
|
||||
MXS_ERROR("Server SSL certificate and key do not match.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Load the RSA CA certificate into the SSL_CTX structure */
|
||||
if (!SSL_CTX_load_verify_locations(service->ctx, service->ssl_ca_cert, NULL)) {
|
||||
if (!SSL_CTX_load_verify_locations(service->ctx, service->ssl_ca_cert, NULL))
|
||||
{
|
||||
MXS_ERROR("Failed to set Certificate Authority file.");
|
||||
return -1;
|
||||
}
|
||||
|
@ -65,19 +65,20 @@ struct users;
|
||||
* 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 servprotocol {
|
||||
typedef struct servprotocol
|
||||
{
|
||||
char *protocol; /**< Protocol module to load */
|
||||
unsigned short port; /**< Port to listen on */
|
||||
char *address; /**< Address to listen with */
|
||||
DCB *listener; /**< The DCB for the listener */
|
||||
struct servprotocol
|
||||
*next; /**< Next service protocol */
|
||||
struct servprotocol *next; /**< Next service protocol */
|
||||
} SERV_PROTOCOL;
|
||||
|
||||
/**
|
||||
* The service statistics structure
|
||||
*/
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
time_t started; /**< The time when the service was started */
|
||||
int n_failed_starts; /**< Number of times this service has failed to start */
|
||||
int n_sessions; /**< Number of sessions created on service since start */
|
||||
@ -90,7 +91,8 @@ typedef struct {
|
||||
database and extact information such as the user table or other
|
||||
database status or configuration data.
|
||||
*/
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
char *name; /**< The user name to use to extract information */
|
||||
char *authdata; /**< The authentication data requied */
|
||||
} SERVICE_USER;
|
||||
@ -99,23 +101,27 @@ typedef struct {
|
||||
* The service refresh rate holds the counter and last load time_t
|
||||
for this service to load users data from the backend database
|
||||
*/
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
int nloads;
|
||||
time_t last;
|
||||
} SERVICE_REFRESH_RATE;
|
||||
|
||||
typedef struct server_ref_t{
|
||||
typedef struct server_ref_t
|
||||
{
|
||||
struct server_ref_t *next;
|
||||
SERVER* server;
|
||||
}SERVER_REF;
|
||||
|
||||
typedef enum {
|
||||
typedef enum
|
||||
{
|
||||
SSL_DISABLED,
|
||||
SSL_ENABLED,
|
||||
SSL_REQUIRED
|
||||
} ssl_mode_t;
|
||||
|
||||
enum{
|
||||
enum
|
||||
{
|
||||
SERVICE_SSLV3,
|
||||
SERVICE_TLS10,
|
||||
#ifdef OPENSSL_1_0
|
||||
@ -142,7 +148,8 @@ enum{
|
||||
* and a set of client side protocol/port pairs used to listen for new connections
|
||||
* to the service.
|
||||
*/
|
||||
typedef struct service {
|
||||
typedef struct service
|
||||
{
|
||||
char *name; /**< The service name */
|
||||
int state; /**< The service state */
|
||||
SERV_PROTOCOL *ports; /**< Linked list of ports and protocols
|
||||
@ -150,10 +157,8 @@ typedef struct service {
|
||||
*/
|
||||
char *routerModule; /**< Name of router module to use */
|
||||
char **routerOptions; /**< Router specific option strings */
|
||||
struct router_object
|
||||
*router; /**< The router we are using */
|
||||
void *router_instance;
|
||||
/**< The router instance for this service */
|
||||
struct router_object *router; /**< The router we are using */
|
||||
void *router_instance; /**< The router instance for this service */
|
||||
char *version_string; /** version string for this service listeners */
|
||||
SERVER_REF *dbref; /** server references */
|
||||
SERVICE_USER credentials; /**< The cedentials of the service user */
|
||||
@ -163,8 +168,7 @@ typedef struct service {
|
||||
int enable_root; /**< Allow root user access */
|
||||
int localhost_match_wildcard_host; /**< Match localhost against wildcard */
|
||||
HASHTABLE *resources; /**< hastable for service resources, i.e. database names */
|
||||
CONFIG_PARAMETER*
|
||||
svc_config_param; /*< list of config params and values */
|
||||
CONFIG_PARAMETER* svc_config_param;/*< list of config params and values */
|
||||
int svc_config_version; /*< Version number of configuration */
|
||||
bool svc_do_shutdown; /*< tells the service to exit loops etc. */
|
||||
bool users_from_all; /*< Load users from one server or all of them */
|
||||
@ -172,10 +176,8 @@ typedef struct service {
|
||||
* when querying them from the server. MySQL Workbench seems
|
||||
* to escape at least the underscore character. */
|
||||
bool optimize_wildcard; /*< Convert wildcard grants to individual database grants */
|
||||
SPINLOCK
|
||||
users_table_spin; /**< The spinlock for users data refresh */
|
||||
SERVICE_REFRESH_RATE
|
||||
rate_limit; /**< The refresh rate limit for users table */
|
||||
SPINLOCK users_table_spin; /**< The spinlock for users data refresh */
|
||||
SERVICE_REFRESH_RATE rate_limit; /**< The refresh rate limit for users table */
|
||||
FILTER_DEF **filters; /**< Ordered list of filters */
|
||||
int n_filters; /**< Number of filters */
|
||||
int conn_timeout; /*< Session timeout in seconds */
|
||||
@ -195,7 +197,13 @@ typedef struct service {
|
||||
bool log_auth_warnings; /*< Log authentication failures and warnings */
|
||||
} SERVICE;
|
||||
|
||||
typedef enum count_spec_t {COUNT_NONE=0, COUNT_ATLEAST, COUNT_EXACT, COUNT_ATMOST} count_spec_t;
|
||||
typedef enum count_spec_t
|
||||
{
|
||||
COUNT_NONE = 0,
|
||||
COUNT_ATLEAST,
|
||||
COUNT_EXACT,
|
||||
COUNT_ATMOST
|
||||
} count_spec_t;
|
||||
|
||||
#define SERVICE_STATE_ALLOC 1 /**< The service has been allocated */
|
||||
#define SERVICE_STATE_STARTED 2 /**< The service has been started */
|
||||
@ -231,28 +239,26 @@ extern void serviceSetRetryOnFailure(SERVICE *service, char* value);
|
||||
extern void serviceWeightBy(SERVICE *, char *);
|
||||
extern char *serviceGetWeightingParameter(SERVICE *);
|
||||
extern int serviceEnableLocalhostMatchWildcardHost(SERVICE *, int);
|
||||
int serviceStripDbEsc(SERVICE* service, int action);
|
||||
int serviceAuthAllServers(SERVICE *service, int action);
|
||||
int serviceOptimizeWildcard(SERVICE *service, int action);
|
||||
extern int serviceStripDbEsc(SERVICE* service, int action);
|
||||
extern int serviceAuthAllServers(SERVICE *service, int action);
|
||||
extern int serviceOptimizeWildcard(SERVICE *service, int action);
|
||||
extern void service_update(SERVICE *, char *, char *, char *);
|
||||
extern int service_refresh_users(SERVICE *);
|
||||
extern void printService(SERVICE *);
|
||||
extern void printAllServices();
|
||||
extern void dprintAllServices(DCB *);
|
||||
|
||||
bool service_set_param_value (
|
||||
SERVICE* service,
|
||||
extern bool service_set_param_value(SERVICE* service,
|
||||
CONFIG_PARAMETER* param,
|
||||
char* valstr,
|
||||
count_spec_t count_spec,
|
||||
config_param_type_t type);
|
||||
|
||||
extern void dprintService(DCB *, SERVICE *);
|
||||
extern void dListServices(DCB *);
|
||||
extern void dListListeners(DCB *);
|
||||
char* service_get_name(SERVICE* svc);
|
||||
void service_shutdown();
|
||||
extern char* service_get_name(SERVICE* svc);
|
||||
extern void service_shutdown();
|
||||
extern int serviceSessionCountAll();
|
||||
extern RESULTSET *serviceGetList();
|
||||
extern RESULTSET *serviceGetListenerList();
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user