Merge branch 'release-1.0beta-refresh' into cmake_build

This commit is contained in:
Markus Makela 2014-09-15 09:43:24 +03:00
commit 4c41dea6fb
14 changed files with 228 additions and 33 deletions

View File

@ -58,6 +58,7 @@ static int authMaxScale(int so, char *user, char *password);
static int sendCommand(int so, char *cmd);
static void DoSource(int so, char *cmd);
static void DoUsage();
static int isquit(char *buf);
#ifdef HISTORY
static char *
@ -289,7 +290,7 @@ int argno = 0;
history(hist, &ev, H_ENTER, buf);
#endif
if (!strcasecmp(buf, "quit"))
if (isquit(buf))
{
break;
}
@ -552,3 +553,23 @@ DoUsage()
printf("Any remaining arguments are treated as MaxScale commands or a file\n");
printf("containing commands to execute.\n");
}
/**
* Check command to see if it is a quit command
*
* @param buf The command buffer
* @return Non-zero if the command should cause maxadmin to quit
*/
static int
isquit(char *buf)
{
char *ptr = buf;
if (!buf)
return 0;
while (*ptr && isspace(*ptr))
ptr++;
if (strncasecmp(ptr, "quit", 4) == 0 || strncasecmp(ptr, "exit", 4) == 0)
return 1;
return 0;
}

View File

@ -35,6 +35,9 @@
* 23/05/14 Massimiliano Pinto Added automatic set of maxscale-id: first listening ipv4_raw + port + pid
* 28/05/14 Massimiliano Pinto Added detect_replication_lag parameter
* 28/08/14 Massimiliano Pinto Added detect_stale_master parameter
* 09/09/14 Massimiliano Pinto Added localhost_match_wildcard_host parameter
* 12/09/14 Mark Riddoch Addition of checks on servers list and
* internal router suppression of messages
*
* @endverbatim
*/
@ -62,6 +65,7 @@ static int handle_global_item(const char *, const char *);
static void global_defaults();
static void check_config_objects(CONFIG_CONTEXT *context);
static int config_truth_value(char *str);
static int internalService(char *router);
static char *config_file = NULL;
static GATEWAY_CONF gateway;
@ -288,6 +292,9 @@ int error_count = 0;
is_rwsplit = true;
}
char *allow_localhost_match_wildcard_host =
config_get_value(obj->parameters, "localhost_match_wildcard_host");
if (obj->element == NULL) /*< if module load failed */
{
LOGIF(LE, (skygw_log_write_flush(
@ -322,6 +329,11 @@ int error_count = 0;
if (weightby)
serviceWeightBy(obj->element, weightby);
if (allow_localhost_match_wildcard_host)
serviceEnableLocalhostMatchWildcardHost(
obj->element,
config_truth_value(allow_localhost_match_wildcard_host));
if (!auth)
auth = config_get_value(obj->parameters,
"auth");
@ -605,36 +617,50 @@ int error_count = 0;
{
char *servers;
char *roptions;
char *router;
char *filters = config_get_value(obj->parameters,
"filters");
servers = config_get_value(obj->parameters, "servers");
roptions = config_get_value(obj->parameters,
"router_options");
router = config_get_value(obj->parameters, "router");
if (servers && obj->element)
{
char *s = strtok(servers, ",");
while (s)
{
CONFIG_CONTEXT *obj1 = context;
int found = 0;
while (obj1)
{
if (strcmp(trim(s), obj1->object) == 0 &&
obj->element && obj1->element)
{
found = 1;
serviceAddBackend(
obj->element,
obj1->element);
}
obj1 = obj1->next;
}
if (!found)
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error: Unable to find "
"server '%s' that is "
"configured as part of "
"service '%s'.",
s, obj->object)));
}
s = strtok(NULL, ",");
}
}
else if (servers == NULL)
else if (servers == NULL && internalService(router) == 0)
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error : The service '%s' is missing a "
"Warning: The service '%s' is missing a "
"definition of the servers that provide "
"the service.",
obj->object)));
@ -787,17 +813,29 @@ int error_count = 0;
while (s)
{
CONFIG_CONTEXT *obj1 = context;
int found = 0;
while (obj1)
{
if (strcmp(s, obj1->object) == 0 &&
obj->element && obj1->element)
{
found = 1;
monitorAddServer(
obj->element,
obj1->element);
}
obj1 = obj1->next;
}
if (!found)
LOGIF(LE,
(skygw_log_write_flush(
LOGFILE_ERROR,
"Error: Unable to find "
"server '%s' that is "
"configured in the "
"monitor '%s'.",
s, obj->object)));
s = strtok(NULL, ",");
}
}
@ -1162,6 +1200,7 @@ SERVER *server;
char* max_slave_conn_str;
char* max_slave_rlag_str;
char *version_string;
char *allow_localhost_match_wildcard_host;
enable_root_user = config_get_value(obj->parameters, "enable_root_user");
@ -1172,6 +1211,8 @@ SERVER *server;
version_string = config_get_value(obj->parameters, "version_string");
allow_localhost_match_wildcard_host = config_get_value(obj->parameters, "localhost_match_wildcard_host");
if (version_string) {
if (service->version_string) {
free(service->version_string);
@ -1185,6 +1226,11 @@ SERVER *server;
auth);
if (enable_root_user)
serviceEnableRootUser(service, atoi(enable_root_user));
if (allow_localhost_match_wildcard_host)
serviceEnableLocalhostMatchWildcardHost(
service,
atoi(allow_localhost_match_wildcard_host));
/** Read, validate and set max_slave_connections */
max_slave_conn_str =
@ -1279,10 +1325,13 @@ SERVER *server;
char *user;
char *auth;
char *enable_root_user;
char *allow_localhost_match_wildcard_host;
enable_root_user =
config_get_value(obj->parameters,
"enable_root_user");
allow_localhost_match_wildcard_host =
config_get_value(obj->parameters, "localhost_match_wildcard_host");
user = config_get_value(obj->parameters,
"user");
@ -1298,6 +1347,11 @@ SERVER *server;
auth);
if (enable_root_user)
serviceEnableRootUser(service, atoi(enable_root_user));
if (allow_localhost_match_wildcard_host)
serviceEnableLocalhostMatchWildcardHost(
service,
atoi(allow_localhost_match_wildcard_host));
}
}
}
@ -1391,11 +1445,13 @@ SERVER *server;
while (s)
{
CONFIG_CONTEXT *obj1 = context;
int found = 0;
while (obj1)
{
if (strcmp(s, obj1->object) == 0 &&
obj->element && obj1->element)
{
found = 1;
if (!serviceHasBackend(obj->element, obj1->element))
{
serviceAddBackend(
@ -1405,6 +1461,16 @@ SERVER *server;
}
obj1 = obj1->next;
}
if (!found)
{
LOGIF(LE, (skygw_log_write_flush(
LOGFILE_ERROR,
"Error: Unable to find "
"server '%s' that is "
"configured as part of "
"service '%s'.",
s, obj->object)));
}
s = strtok(NULL, ",");
}
}
@ -1503,6 +1569,7 @@ static char *service_params[] =
"user",
"passwd",
"enable_root_user",
"localhost_match_wildcard_host",
"max_slave_connections",
"max_slave_replication_lag",
"use_sql_variables_in", /*< rwsplit only */
@ -1667,3 +1734,29 @@ config_truth_value(char *str)
return atoi(str);
}
static char *InternalRouters[] = {
"debugcli",
"cli",
NULL
};
/**
* Determine if the router is one of the special internal services that
* MaxScale offers.
*
* @param router The router name
* @return Non-zero if the router is in the InternalRouters table
*/
static int
internalService(char *router)
{
int i;
if (router)
{
for (i = 0; InternalRouters[i]; i++)
if (strcmp(router, InternalRouters[i]) == 0)
return 1;
}
return 0;
}

View File

@ -375,23 +375,23 @@ char *stat;
if (ptr)
{
dcb_printf(dcb, "Servers.\n");
dcb_printf(dcb, "-------------------+-----------------+-------+----------------------+------------\n");
dcb_printf(dcb, "%-18s | %-15s | Port | %-20s | Connections\n",
dcb_printf(dcb, "-------------------+-----------------+-------+-------------+--------------------\n");
dcb_printf(dcb, "%-18s | %-15s | Port | Connections | %-20s\n",
"Server", "Address", "Status");
dcb_printf(dcb, "-------------------+-----------------+-------+----------------------+------------\n");
dcb_printf(dcb, "-------------------+-----------------+-------+-------------+--------------------\n");
}
while (ptr)
{
stat = server_status(ptr);
dcb_printf(dcb, "%-18s | %-15s | %5d | %-20s | %4d\n",
dcb_printf(dcb, "%-18s | %-15s | %5d | %11d | %s\n",
ptr->unique_name, ptr->name,
ptr->port, stat,
ptr->stats.n_current);
ptr->port,
ptr->stats.n_current, stat);
free(stat);
ptr = ptr->next;
}
if (allServers)
dcb_printf(dcb, "-------------------+-----------------+-------+----------------------+------------\n\n");
dcb_printf(dcb, "-------------------+-----------------+-------+-------------+--------------------\n");
spinlock_release(&server_spin);
}
@ -424,6 +424,8 @@ char *status = NULL;
strcat(status, "Slave of External Server, ");
if (server->status & SERVER_STALE_STATUS)
strcat(status, "Stale Status, ");
if (server->status & SERVER_AUTH_ERROR)
strcat(status, "Auth Error, ");
if (server->status & SERVER_RUNNING)
strcat(status, "Running");
else

View File

@ -31,6 +31,7 @@
* 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
* 09/09/14 Massimiliano Pinto Added service option for localhost authentication
*
* @endverbatim
*/
@ -128,6 +129,7 @@ SERVICE *service;
service->credentials.name = NULL;
service->credentials.authdata = NULL;
service->enable_root = 0;
service->localhost_match_wildcard_host = 0;
service->routerOptions = NULL;
service->databases = NULL;
service->svc_config_param = NULL;
@ -1288,3 +1290,23 @@ serviceGetWeightingParameter(SERVICE *service)
{
return service->weightby;
}
/**
* Enable/Disable localhost authentication match criteria
* associated with this service.
*
* @param service The service we are setting the data for
* @param action 1 for enable, 0 for disable access
* @return 0 on failure
*/
int
serviceEnableLocalhostMatchWildcardHost(SERVICE *service, int action)
{
if (action != 0 && action != 1)
return 0;
service->localhost_match_wildcard_host = action;
return 1;
}

View File

@ -693,7 +693,17 @@ int i;
service->name)));
return 0;
}
session->tail = *tail;
/*
* filterUpstream may simply return the 3 parameter if
* the filter has no upstream entry point. So no need
* to copy the contents or free tail in this case.
*/
if (tail != &session->tail)
{
session->tail = *tail;
free(tail);
}
}
return 1;

View File

@ -105,6 +105,7 @@ typedef struct server {
#define SERVER_MAINT 0x0020 /**<< Server is in maintenance mode */
#define SERVER_SLAVE_OF_EXTERNAL_MASTER 0x0040 /**<< Server is slave of a Master outside the provided replication topology */
#define SERVER_STALE_STATUS 0x0080 /**<< Server stale status, monitor didn't update it */
#define SERVER_AUTH_ERROR 0x1000 /**<< Authentication erorr from monitor */
/**
* Is the server running - the macro returns true if the server is marked as running

View File

@ -44,6 +44,7 @@
* struct
* 29/05/14 Mark Riddoch Filter API mechanism
* 26/06/14 Mark Riddoch Added WeightBy support
* 09/09/14 Massimiliano Pinto Added service option for localhost authentication
*
* @endverbatim
*/
@ -122,6 +123,7 @@ typedef struct service {
SERVICE_STATS stats; /**< The service statistics */
struct users *users; /**< The user data for this service */
int enable_root; /**< Allow root user access */
int localhost_match_wildcard_host; /**< Match localhost against wildcard */
CONFIG_PARAMETER*
svc_config_param; /*< list of config params and values */
int svc_config_version; /*< Version number of configuration */
@ -161,6 +163,7 @@ extern void serviceSetFilters(SERVICE *, char *);
extern int serviceEnableRootUser(SERVICE *, int );
extern void serviceWeightBy(SERVICE *, char *);
extern char *serviceGetWeightingParameter(SERVICE *);
extern int serviceEnableLocalhostMatchWildcardHost(SERVICE *, int);
extern void service_update(SERVICE *, char *, char *, char *);
extern int service_refresh_users(SERVICE *);
extern void printService(SERVICE *);

View File

@ -335,10 +335,18 @@ char *server_string;
database->server->port,
mysql_error(database->con))));
server_clear_status(database->server, SERVER_RUNNING);
if (mysql_errno(database->con) == ER_ACCESS_DENIED_ERROR)
{
server_set_status(database->server, SERVER_AUTH_ERROR);
}
database->server->node_id = -1;
free(dpwd);
return;
}
else
{
server_clear_status(database->server, SERVER_AUTH_ERROR);
}
free(dpwd);
}
@ -351,7 +359,9 @@ char *server_string;
/* get server version string */
server_string = (char *)mysql_get_server_info(database->con);
if (server_string) {
database->server->server_string = strdup(server_string);
database->server->server_string = realloc(database->server->server_string, strlen(server_string)+1);
if (database->server->server_string)
strcpy(database->server->server_string, server_string);
}
/* Check if the the Galera FSM shows this node is joined to the cluster */

View File

@ -400,6 +400,11 @@ char *server_string;
* Store server NOT running in server and monitor server pending struct
*
*/
if (mysql_errno(database->con) == ER_ACCESS_DENIED_ERROR)
{
server_set_status(database->server, SERVER_AUTH_ERROR);
monitor_set_pending_status(database, SERVER_AUTH_ERROR);
}
server_clear_status(database->server, SERVER_RUNNING);
monitor_clear_pending_status(database, SERVER_RUNNING);
@ -417,6 +422,11 @@ char *server_string;
return;
}
else
{
server_clear_status(database->server, SERVER_AUTH_ERROR);
monitor_clear_pending_status(database, SERVER_AUTH_ERROR);
}
free(dpwd);
}
/* Store current status in both server and monitor server pending struct */
@ -429,7 +439,9 @@ char *server_string;
/* get server version string */
server_string = (char *)mysql_get_server_info(database->con);
if (server_string) {
database->server->server_string = strdup(server_string);
database->server->server_string = realloc(database->server->server_string, strlen(server_string)+1);
if (database->server->server_string)
strcpy(database->server->server_string, server_string);
}
/* get server_id form current node */

View File

@ -329,10 +329,18 @@ char *server_string;
database->server->port,
mysql_error(database->con))));
server_clear_status(database->server, SERVER_RUNNING);
if (mysql_errno(database->con) == ER_ACCESS_DENIED_ERROR)
{
server_set_status(database->server, SERVER_AUTH_ERROR);
}
database->server->node_id = -1;
free(dpwd);
return;
}
else
{
server_clear_status(database->server, SERVER_AUTH_ERROR);
}
free(dpwd);
}
@ -345,7 +353,9 @@ char *server_string;
/* get server version string */
server_string = (char *)mysql_get_server_info(database->con);
if (server_string) {
database->server->server_string = strdup(server_string);
database->server->server_string = realloc(database->server->server_string, strlen(server_string)+1);
if (database->server->server_string)
strcpy(database->server->server_string, server_string);
}
/* Check if the the SQL node is able to contact one or more data nodes */

View File

@ -492,6 +492,7 @@ static int gw_read_backend_event(DCB *dcb) {
dcb->dcb_readqueue = NULL;
}
}
/** This may be either short prefix of a packet, or the tail of it. */
else
{
if (nbytes_read < 5)

View File

@ -42,6 +42,7 @@
#include <mysql_client_server_protocol.h>
#include <gw.h>
#include <modinfo.h>
#include <sys/stat.h>
MODULE_INFO info = {
MODULE_API_PROTOCOL,
@ -552,15 +553,16 @@ int gw_read_client_event(
*/
if (dcb->dcb_readqueue)
{
uint8_t* data = (uint8_t *)GWBUF_DATA(read_buffer);
uint8_t* data;
read_buffer = gwbuf_append(dcb->dcb_readqueue, read_buffer);
nbytes_read = gwbuf_length(read_buffer);
dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, read_buffer);
nbytes_read = gwbuf_length(dcb->dcb_readqueue);
data = (uint8_t *)GWBUF_DATA(dcb->dcb_readqueue);
if (nbytes_read < 3 || nbytes_read < MYSQL_GET_PACKET_LEN(data))
{
rc = 0;
goto return_rc;
rc = 0;
goto return_rc;
}
else
{
@ -578,8 +580,8 @@ int gw_read_client_event(
if (nbytes_read < 3 || nbytes_read < MYSQL_GET_PACKET_LEN(data)+4)
{
gwbuf_append(dcb->dcb_readqueue, read_buffer);
rc = 0;
dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, read_buffer);
rc = 0;
goto return_rc;
}
}
@ -789,7 +791,7 @@ int gw_read_client_event(
if (read_buffer != NULL)
{
/** add incomplete mysql packet to read queue */
gwbuf_append(dcb->dcb_readqueue, read_buffer);
dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, read_buffer);
}
}
else
@ -1443,7 +1445,11 @@ static int route_by_statement(
do
{
ss_dassert(GWBUF_IS_TYPE_MYSQL((*p_readbuf)));
/**
* Collect incoming bytes to a buffer until complete packet has
* arrived and then return the buffer.
*/
packetbuf = gw_MySQL_get_next_packet(p_readbuf);
if (packetbuf != NULL)

View File

@ -26,6 +26,11 @@
* 04/09/2013 Massimiliano Pinto Added dcb NULL assert in mysql_send_custom_error
* 12/09/2013 Massimiliano Pinto Added checks in gw_decode_mysql_server_handshake and gw_read_backend_handshake
* 10/02/2014 Massimiliano Pinto Added MySQL Authentication with user@host
* 10/09/2014 Massimiliano Pinto Added MySQL Authentication option enabling localhost match with any host (wildcard %)
* Backend server configuration may differ so default is 0, don't match and an explicit
* localhost entry should be added for the selected user in the backends.
* Setting to 1 allow localhost (127.0.0.1 or socket) to match the any host grant via
* user@%
*
*/
@ -1345,12 +1350,12 @@ int gw_find_mysql_user_password_sha1(char *username, uint8_t *gateway_password,
* The check for localhost is 127.0.0.1 (IPv4 only)
*/
if (key.ipv4.sin_addr.s_addr == 0x0100007F) {
if ((key.ipv4.sin_addr.s_addr == 0x0100007F) && !dcb->service->localhost_match_wildcard_host) {
/* Skip the wildcard check and return 1 */
LOGIF(LD,
LOGIF(LE,
(skygw_log_write_flush(
LOGFILE_DEBUG,
"%lu [MySQL Client Auth], user [%s@%s] not existent",
LOGFILE_ERROR,
"%lu [MySQL Client Auth], user [%s@%s] not found, please try with 'localhost_match_wildcard_host=1' in service definition",
pthread_self(),
key.user,
dcb->remote)));
@ -1530,9 +1535,7 @@ GWBUF* gw_MySQL_get_next_packet(
{
packetbuf = NULL;
goto return_packetbuf;
}
buflen = GWBUF_LENGTH((readbuf));
}
totalbuflen = gwbuf_length(readbuf);
data = (uint8_t *)GWBUF_DATA((readbuf));
packetlen = MYSQL_GET_PACKET_LEN(data)+4;
@ -1556,6 +1559,7 @@ GWBUF* gw_MySQL_get_next_packet(
uint8_t* src = GWBUF_DATA((*p_readbuf));
size_t bytestocopy;
buflen = GWBUF_LENGTH((*p_readbuf));
bytestocopy = MIN(buflen,packetlen-nbytes_copied);
memcpy(target+nbytes_copied, src, bytestocopy);
@ -1569,7 +1573,6 @@ return_packetbuf:
return packetbuf;
}
/**
* Move <npackets> from buffer pointed to by <*p_readbuf>.
*/
@ -1694,8 +1697,9 @@ void protocol_add_srv_command(
MySQLProtocol* p,
mysql_server_cmd_t cmd)
{
#if defined(SS_DEBUG)
server_command_t* c;
#endif
spinlock_acquire(&p->protocol_lock);
if (p->protocol_state != MYSQL_PROTOCOL_ACTIVE)

View File

@ -1949,7 +1949,7 @@ static int routeQuery(
}
rses_end_locked_router_action(router_cli_ses);
retblock:
#if defined(SS_DEBUG)
#if defined(SS_DEBUG2)
{
char* canonical_query_str;