Merge branch 'develop' into logmanager_stdout

This commit is contained in:
Markus Makela
2015-04-30 04:28:40 +03:00
3 changed files with 94 additions and 18 deletions

View File

@ -74,7 +74,7 @@ Each mandatory rule accepts one or more optional parameters. These are to be def
#### `at_times` #### `at_times`
This rule expects a list of time ranges that define the times when the rule in question is active. The time formats are expected to be ISO-8601 compliant and to be separated by a single dash (the - character). For example, to define the active period of a rule to be 5pm to 7pm, you would include `at times 17:00:00-19:00:00` in the rule definition. This rule expects a list of time ranges that define the times when the rule in question is active. The time formats are expected to be ISO-8601 compliant and to be separated by a single dash (the - character). For example, to define the active period of a rule to be 5pm to 7pm, you would include `at times 17:00:00-19:00:00` in the rule definition. The rule uses local time to check if the rule is active and has a precision of one second.
#### `on_queries` #### `on_queries`

View File

@ -86,6 +86,14 @@ MODULE_INFO info = {
static char *version_str = "V1.0.0"; static char *version_str = "V1.0.0";
static char* required_rules[] = {
"wildcard",
"columns",
"regex",
"limit_queries",
"no_where_clause",
NULL
};
/* /*
* The filter entry points * The filter entry points
*/ */
@ -861,6 +869,10 @@ bool parse_rule(char* rule, FW_INSTANCE* instance)
bool allow,deny,mode; bool allow,deny,mode;
RULE* ruledef = NULL; RULE* ruledef = NULL;
bool rval = true; bool rval = true;
bool req_defined,oq_def,at_def;
int i;
req_defined = oq_def = at_def = false;
if(tok == NULL) if(tok == NULL)
{ {
@ -920,7 +932,7 @@ bool parse_rule(char* rule, FW_INSTANCE* instance)
} }
else else
{ {
skygw_log_write(LOGFILE_ERROR,"Error : Unknown token in rule file: %s",tok); skygw_log_write(LOGFILE_ERROR,"Error : Unknown token in rule '%s': %s",rule,tok);
rval = false; rval = false;
goto retblock; goto retblock;
} }
@ -946,6 +958,25 @@ bool parse_rule(char* rule, FW_INSTANCE* instance)
while(tok) while(tok)
{ {
reparse_rule:
for(i = 0;required_rules[i] != NULL;i++)
{
if(strcmp(tok,required_rules[i]) == 0)
{
if(req_defined)
{
skygw_log_write(LOGFILE_ERROR,"dbfwfilter: Rule parsing failed, Multiple non-optional rules: %s",rule);
rval = false;
goto retblock;
}
else
{
req_defined = true;
}
}
}
if(strcmp(tok,"wildcard") == 0) if(strcmp(tok,"wildcard") == 0)
{ {
ruledef->type = RT_WILDCARD; ruledef->type = RT_WILDCARD;
@ -970,11 +1001,18 @@ bool parse_rule(char* rule, FW_INSTANCE* instance)
} }
else if(strcmp(tok,"at_times") == 0) else if(strcmp(tok,"at_times") == 0)
{ {
if(at_def)
{
skygw_log_write(LOGFILE_ERROR,"dbfwfilter: Rule parsing failed, multiple 'at_times' tokens: %s",rule);
rval = false;
goto retblock;
}
at_def = true;
tok = strtok_r(NULL, " ,",&saveptr); tok = strtok_r(NULL, " ,",&saveptr);
TIMERANGE *tr = NULL; TIMERANGE *tr = NULL;
while(tok){ while(tok){
if(strcmp(tok,"on_queries") == 0)
break;
if(!check_time(tok)) if(!check_time(tok))
{ {
skygw_log_write(LOGFILE_ERROR,"dbfwfilter: Rule parsing failed, malformed time definition: %s",tok); skygw_log_write(LOGFILE_ERROR,"dbfwfilter: Rule parsing failed, malformed time definition: %s",tok);
@ -1000,8 +1038,12 @@ bool parse_rule(char* rule, FW_INSTANCE* instance)
tr = tmp; tr = tmp;
tok = strtok_r(NULL, " ,",&saveptr); tok = strtok_r(NULL, " ,",&saveptr);
} }
ruledef->active = tr; ruledef->active = tr;
if(strcmp(tok,"on_queries") == 0)
goto reparse_rule;
} }
else if(strcmp(tok,"regex") == 0) else if(strcmp(tok,"regex") == 0)
{ {
@ -1119,14 +1161,24 @@ bool parse_rule(char* rule, FW_INSTANCE* instance)
skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule parsing failed, not a number: '%s'.", tok); skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule parsing failed, not a number: '%s'.", tok);
goto retblock; goto retblock;
} }
if(qs->limit < 1){
free(qs);
rval = false;
skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Bad query amount: %s", tok);
goto retblock;
}
errptr = NULL; errptr = NULL;
tok = strtok_r(NULL," ",&saveptr); tok = strtok_r(NULL," ",&saveptr);
if(tok == NULL){ if(tok == NULL){
free(qs); free(qs);
rval = false; rval = false;
skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Missing parameter in limit_queries: '%s'.", rule); skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Missing parameter in limit_queries: '%s'.", rule);
goto retblock; goto retblock;
} }
qs->period = strtod(tok,&errptr); qs->period = strtod(tok,&errptr);
if(errptr && *errptr != '\0') if(errptr && *errptr != '\0')
@ -1136,9 +1188,17 @@ bool parse_rule(char* rule, FW_INSTANCE* instance)
skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule parsing failed, not a number: '%s'.", tok); skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Rule parsing failed, not a number: '%s'.", tok);
goto retblock; goto retblock;
} }
errptr = NULL;
if(qs->period < 1){
free(qs);
rval = false;
skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Bad time period: %s", tok);
goto retblock;
}
errptr = NULL;
tok = strtok_r(NULL," ",&saveptr); tok = strtok_r(NULL," ",&saveptr);
if(tok == NULL){ if(tok == NULL){
free(qs); free(qs);
rval = false; rval = false;
@ -1155,6 +1215,13 @@ bool parse_rule(char* rule, FW_INSTANCE* instance)
goto retblock; goto retblock;
} }
if(qs->cooldown < 1){
free(qs);
rval = false;
skygw_log_write(LOGFILE_ERROR, "dbfwfilter: Bad blocking period: %s", tok);
goto retblock;
}
ruledef->type = RT_THROTTLE; ruledef->type = RT_THROTTLE;
ruledef->data = (void*)qs; ruledef->data = (void*)qs;
} }
@ -1165,6 +1232,13 @@ bool parse_rule(char* rule, FW_INSTANCE* instance)
} }
else if(strcmp(tok,"on_queries") == 0) else if(strcmp(tok,"on_queries") == 0)
{ {
if(oq_def)
{
skygw_log_write(LOGFILE_ERROR,"dbfwfilter: Rule parsing failed, multiple 'on_queries' tokens: %s",rule);
rval = false;
goto retblock;
}
oq_def = true;
tok = strtok_r(NULL," ",&saveptr); tok = strtok_r(NULL," ",&saveptr);
if(tok == NULL) if(tok == NULL)

View File

@ -531,18 +531,20 @@ char *server_string;
} }
/* get variable 'read_only' set by an external component */ /* get variable 'read_only' set by an external component */
if (mysql_query(database->con, "SHOW GLOBAL VARIABLES LIKE 'read_only'") == 0 if (mysql_query(database->con, "SHOW GLOBAL VARIABLES LIKE 'read_only'") == 0
&& (result = mysql_store_result(database->con)) != NULL) && (result = mysql_store_result(database->con)) != NULL)
{ {
num_fields = mysql_num_fields(result); num_fields = mysql_num_fields(result);
while ((row = mysql_fetch_row(result))) while ((row = mysql_fetch_row(result)))
{ {
if (strncasecmp(row[1], "OFF", 3) == 0) { if (strncasecmp(row[1], "OFF", 3) == 0) {
ismaster = 1; ismaster = 1;
} } else {
} isslave = 1;
mysql_free_result(result); }
} }
mysql_free_result(result);
}
/* Remove addition info */ /* Remove addition info */
monitor_clear_pending_status(database, SERVER_STALE_STATUS); monitor_clear_pending_status(database, SERVER_STALE_STATUS);
@ -563,7 +565,7 @@ char *server_string;
} }
/* Set the Master role */ /* Set the Master role */
if (isslave && ismaster) if (ismaster)
{ {
monitor_clear_pending_status(database, SERVER_SLAVE); monitor_clear_pending_status(database, SERVER_SLAVE);
monitor_set_pending_status(database, SERVER_MASTER); monitor_set_pending_status(database, SERVER_MASTER);