Merge branch 'develop' into MXS-544
This commit is contained in:
@ -2,7 +2,7 @@ if(BUILD_RABBITMQ)
|
||||
if(RABBITMQ_FOUND)
|
||||
include_directories(${RABBITMQ_HEADERS})
|
||||
add_library(mqfilter SHARED mqfilter.c)
|
||||
target_link_libraries(mqfilter query_classifier maxscale-common ${RABBITMQ_LIBRARIES})
|
||||
target_link_libraries(mqfilter maxscale-common ${RABBITMQ_LIBRARIES})
|
||||
add_dependencies(mqfilter pcre2)
|
||||
install(TARGETS mqfilter DESTINATION ${MAXSCALE_LIBDIR})
|
||||
else()
|
||||
@ -36,11 +36,6 @@ target_link_libraries(topfilter maxscale-common)
|
||||
set_target_properties(topfilter PROPERTIES VERSION "1.0.1")
|
||||
install(TARGETS topfilter DESTINATION ${MAXSCALE_LIBDIR})
|
||||
|
||||
add_library(dbfwfilter SHARED dbfwfilter.c)
|
||||
target_link_libraries(dbfwfilter maxscale-common query_classifier)
|
||||
set_target_properties(dbfwfilter PROPERTIES VERSION "1.0.0")
|
||||
install(TARGETS dbfwfilter DESTINATION ${MAXSCALE_LIBDIR})
|
||||
|
||||
add_library(namedserverfilter SHARED namedserverfilter.c)
|
||||
target_link_libraries(namedserverfilter maxscale-common)
|
||||
set_target_properties(namedserverfilter PROPERTIES VERSION "1.1.0")
|
||||
@ -49,7 +44,7 @@ install(TARGETS namedserverfilter DESTINATION ${MAXSCALE_LIBDIR})
|
||||
|
||||
if(BUILD_SLAVELAG)
|
||||
add_library(slavelag SHARED slavelag.c)
|
||||
target_link_libraries(slavelag maxscale-common query_classifier)
|
||||
target_link_libraries(slavelag maxscale-common)
|
||||
set_target_properties(slavelag PROPERTIES VERSION "1.1.0")
|
||||
install(TARGETS slavelag DESTINATION ${MAXSCALE_LIBDIR})
|
||||
endif()
|
||||
@ -57,11 +52,12 @@ endif()
|
||||
if(BUILD_TOOLS)
|
||||
add_executable(ruleparser dbfwfilter.c)
|
||||
target_compile_definitions(ruleparser PUBLIC "BUILD_RULE_PARSER")
|
||||
target_link_libraries(ruleparser maxscale-common query_classifier)
|
||||
target_link_libraries(ruleparser maxscale-common)
|
||||
install(TARGETS ruleparser DESTINATION ${MAXSCALE_BINDIR})
|
||||
endif()
|
||||
|
||||
add_subdirectory(hint)
|
||||
add_subdirectory(dbfwfilter)
|
||||
|
||||
if(BUILD_TESTS)
|
||||
add_subdirectory(test)
|
||||
|
||||
15
server/modules/filter/dbfwfilter/CMakeLists.txt
Normal file
15
server/modules/filter/dbfwfilter/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
find_package(FLEX)
|
||||
find_package(BISON)
|
||||
if(BISON_FOUND AND FLEX_FOUND)
|
||||
bison_target(ruleparser ruleparser.y ${CMAKE_CURRENT_BINARY_DIR}/ruleparser.c COMPILE_FLAGS "--defines=${CMAKE_CURRENT_BINARY_DIR}/ruleparser.yy.h")
|
||||
flex_target(token token.l ${CMAKE_CURRENT_BINARY_DIR}/token.c COMPILE_FLAGS "--header-file=${CMAKE_CURRENT_BINARY_DIR}/lex.yy.h")
|
||||
add_flex_bison_dependency(token ruleparser)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_library(dbfwfilter SHARED dbfwfilter.c ${BISON_ruleparser_OUTPUTS} ${FLEX_token_OUTPUTS})
|
||||
target_link_libraries(dbfwfilter maxscale-common)
|
||||
set_target_properties(dbfwfilter PROPERTIES VERSION "1.0.0")
|
||||
install(TARGETS dbfwfilter DESTINATION ${MAXSCALE_LIBDIR})
|
||||
else()
|
||||
mesage(FATAL_ERROR "Could not find Bison or Flex: ${BISON_EXECUTABLE} ${FLEX_EXECUTABLE}")
|
||||
endif()
|
||||
File diff suppressed because it is too large
Load Diff
58
server/modules/filter/dbfwfilter/dbfwfilter.h
Normal file
58
server/modules/filter/dbfwfilter/dbfwfilter.h
Normal file
@ -0,0 +1,58 @@
|
||||
#ifndef _DBFWFILTER_H
|
||||
#define _DBFWFILTER_H
|
||||
|
||||
/*
|
||||
* This file is distributed as part of MaxScale by MariaDB Corporation. It is free
|
||||
* software: you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation,
|
||||
* version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright MariaDB Corporation Ab 2016
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file dbfwfilter.h - Database firewall filter
|
||||
*
|
||||
* External functions used by the rule parser. These functions are called from
|
||||
* the generater parser which is created from the ruleparser.y and token.l files.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/** Matching type */
|
||||
enum match_type
|
||||
{
|
||||
FWTOK_MATCH_ANY,
|
||||
FWTOK_MATCH_ALL,
|
||||
FWTOK_MATCH_STRICT_ALL
|
||||
};
|
||||
|
||||
/** Prototype for the parser's error handler */
|
||||
void dbfw_yyerror(void* scanner, const char* error);
|
||||
|
||||
/** Rule creation and definition functions */
|
||||
bool create_rule(void* scanner, const char* name);
|
||||
void define_wildcard_rule(void* scanner);
|
||||
void define_where_clause_rule(void* scanner);
|
||||
bool define_regex_rule(void* scanner, char* pattern);
|
||||
bool define_columns_rule(void* scanner, char* columns);
|
||||
bool define_limit_queries_rule(void* scanner, int max, int timeperiod, int holdoff);
|
||||
bool add_at_times_rule(void* scanner, const char* range);
|
||||
void add_on_queries_rule(void* scanner, const char* sql);
|
||||
|
||||
/** User creation functions */
|
||||
bool add_active_user(void* scanner, const char* name);
|
||||
bool add_active_rule(void* scanner, const char* name);
|
||||
void set_matching_mode(void* scanner, enum match_type mode);
|
||||
bool create_user_templates(void* scanner);
|
||||
|
||||
#endif
|
||||
131
server/modules/filter/dbfwfilter/ruleparser.y
Normal file
131
server/modules/filter/dbfwfilter/ruleparser.y
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* This file is distributed as part of MaxScale by MariaDB Corporation. It is free
|
||||
* software: you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation,
|
||||
* version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright MariaDB Corporation Ab 2016
|
||||
*/
|
||||
|
||||
%union{
|
||||
int intval;
|
||||
char* strval;
|
||||
float floatval;
|
||||
}
|
||||
|
||||
%{
|
||||
#include <lex.yy.h>
|
||||
#include <dbfwfilter.h>
|
||||
%}
|
||||
|
||||
/** We need a reentrant scanner so no global variables are used */
|
||||
%pure-parser
|
||||
|
||||
/** Prefix all functions */
|
||||
%name-prefix="dbfw_yy"
|
||||
|
||||
/** The pure parser requires one extra parameter */
|
||||
%parse-param {void* scanner}
|
||||
%lex-param {void* scanner}
|
||||
|
||||
/** Terminal symbols */
|
||||
%token FWTOK_RULE <strval>FWTOK_RULENAME FWTOK_USERS <strval>FWTOK_USER FWTOK_RULES FWTOK_MATCH FWTOK_ANY FWTOK_ALL FWTOK_STRICT_ALL FWTOK_DENY
|
||||
%token FWTOK_WILDCARD FWTOK_COLUMNS FWTOK_REGEX FWTOK_LIMIT_QUERIES FWTOK_WHERE_CLAUSE FWTOK_AT_TIMES FWTOK_ON_QUERIES
|
||||
%token <strval>FWTOK_SQLOP FWTOK_COMMENT <intval>FWTOK_INT <floatval>FWTOK_FLOAT FWTOK_PIPE <strval>FWTOK_TIME
|
||||
%token <strval>FWTOK_BTSTR <strval>FWTOK_QUOTEDSTR <strval>FWTOK_STR
|
||||
|
||||
/** Non-terminal symbols */
|
||||
%type <strval>rulename
|
||||
%type <strval>cond
|
||||
%type <strval>columnlist
|
||||
%type <strval>orlist
|
||||
|
||||
%%
|
||||
|
||||
input:
|
||||
| input line
|
||||
;
|
||||
|
||||
line:
|
||||
'\n'
|
||||
| rule '\n'
|
||||
| user '\n'
|
||||
| FWTOK_COMMENT '\n'
|
||||
;
|
||||
|
||||
rule:
|
||||
FWTOK_RULE rulename {if (!create_rule(scanner, $2)){YYERROR;}} FWTOK_DENY ruleparams
|
||||
;
|
||||
|
||||
ruleparams:
|
||||
mandatory optional optional
|
||||
| mandatory optional
|
||||
| mandatory
|
||||
| optional
|
||||
;
|
||||
|
||||
rulename:
|
||||
FWTOK_RULENAME
|
||||
| FWTOK_STR
|
||||
;
|
||||
|
||||
user:
|
||||
FWTOK_USERS userlist FWTOK_MATCH cond FWTOK_RULES namelist
|
||||
{if (!create_user_templates(scanner)){YYERROR;}}
|
||||
;
|
||||
|
||||
userlist:
|
||||
FWTOK_USER {if (!add_active_user(scanner, $1)){YYERROR;}}
|
||||
| userlist FWTOK_USER {if (!add_active_user(scanner, $2)){YYERROR;}}
|
||||
;
|
||||
|
||||
namelist:
|
||||
rulename {if (!add_active_rule(scanner, $1)){YYERROR;}}
|
||||
| namelist rulename {if (!add_active_rule(scanner, $2)){YYERROR;}}
|
||||
;
|
||||
|
||||
cond:
|
||||
FWTOK_ANY {set_matching_mode(scanner, FWTOK_MATCH_ANY);}
|
||||
| FWTOK_ALL {set_matching_mode(scanner, FWTOK_MATCH_ALL);}
|
||||
| FWTOK_STRICT_ALL {set_matching_mode(scanner, FWTOK_MATCH_STRICT_ALL);}
|
||||
;
|
||||
|
||||
mandatory:
|
||||
FWTOK_WILDCARD {define_wildcard_rule(scanner);}
|
||||
| FWTOK_WHERE_CLAUSE {define_where_clause_rule(scanner);}
|
||||
| FWTOK_LIMIT_QUERIES FWTOK_INT FWTOK_INT FWTOK_INT
|
||||
{if (!define_limit_queries_rule(scanner, $2, $3, $4)){YYERROR;}}
|
||||
| FWTOK_REGEX FWTOK_QUOTEDSTR {if (!define_regex_rule(scanner, $2)){YYERROR;}}
|
||||
| FWTOK_COLUMNS columnlist
|
||||
;
|
||||
|
||||
columnlist:
|
||||
FWTOK_BTSTR {if (!define_columns_rule(scanner, $1)){YYERROR;}}
|
||||
| FWTOK_STR {if (!define_columns_rule(scanner, $1)){YYERROR;}}
|
||||
| columnlist FWTOK_BTSTR {if (!define_columns_rule(scanner, $2)){YYERROR;}}
|
||||
| columnlist FWTOK_STR {if (!define_columns_rule(scanner, $2)){YYERROR;}}
|
||||
;
|
||||
|
||||
optional:
|
||||
FWTOK_AT_TIMES timelist
|
||||
| FWTOK_ON_QUERIES orlist
|
||||
;
|
||||
|
||||
timelist:
|
||||
FWTOK_TIME {if (!add_at_times_rule(scanner, $1)){YYERROR;}}
|
||||
| timelist FWTOK_TIME {if (!add_at_times_rule(scanner, $2)){YYERROR;}}
|
||||
;
|
||||
|
||||
orlist:
|
||||
FWTOK_SQLOP {add_on_queries_rule(scanner, $1);}
|
||||
| orlist FWTOK_PIPE FWTOK_SQLOP {add_on_queries_rule(scanner, $3);}
|
||||
;
|
||||
76
server/modules/filter/dbfwfilter/token.l
Normal file
76
server/modules/filter/dbfwfilter/token.l
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* This file is distributed as part of MaxScale by MariaDB Corporation. It is free
|
||||
* software: you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation,
|
||||
* version 2.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright MariaDB Corporation Ab 2016
|
||||
*/
|
||||
|
||||
%{
|
||||
#include <ruleparser.yy.h>
|
||||
|
||||
%}
|
||||
|
||||
%option reentrant noyywrap bison-bridge prefix="dbfw_yy"
|
||||
%option yylineno
|
||||
|
||||
RULENAME [-_[:alnum:][:punct:]]+
|
||||
STR [_[:alnum:]]+
|
||||
TIME [0-9]{2}:[0-9]{2}:[0-9]{2}-[0-9]{2}:[0-9]{2}:[0-9]{2}
|
||||
QSTR (\"[^\"]*\")|('[^']*')
|
||||
SPACE [[:space:]]*
|
||||
COMMENT ^[[:space:]]*#.*
|
||||
INT [0-9]+
|
||||
FLOAT [0-9]+[.][0-9]+
|
||||
SQL select|insert|update|delete
|
||||
PIPE [|]
|
||||
USER [^[:space:]]*[@]
|
||||
IP [0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}
|
||||
BTSTR `[^`]*`
|
||||
USTR [%-_[:alnum:][:punct:]]+
|
||||
|
||||
%%
|
||||
"\n"+ return '\n';
|
||||
{COMMENT} return FWTOK_COMMENT;
|
||||
deny|allow return FWTOK_DENY; /** This should be removed at some point */
|
||||
rule return FWTOK_RULE;
|
||||
no_where_clause return FWTOK_WHERE_CLAUSE;
|
||||
wildcard return FWTOK_WILDCARD;
|
||||
columns return FWTOK_COLUMNS;
|
||||
regex return FWTOK_REGEX;
|
||||
limit_queries return FWTOK_LIMIT_QUERIES;
|
||||
at_times return FWTOK_AT_TIMES;
|
||||
on_queries return FWTOK_ON_QUERIES;
|
||||
users return FWTOK_USERS;
|
||||
rules return FWTOK_RULES;
|
||||
match return FWTOK_MATCH;
|
||||
any return FWTOK_ANY;
|
||||
all return FWTOK_ALL;
|
||||
strict_all return FWTOK_STRICT_ALL;
|
||||
{USTR}@{USTR} yylval->strval = yytext;return FWTOK_USER;
|
||||
{BTSTR}@{BTSTR} yylval->strval = yytext;return FWTOK_USER;
|
||||
{QSTR}@{QSTR} yylval->strval = yytext;return FWTOK_USER;
|
||||
({SQL}{SPACE}{PIPE}{SPACE})*{SQL} {
|
||||
yylval->strval = yytext;return FWTOK_SQLOP;
|
||||
}
|
||||
{TIME} yylval->strval = yytext;return FWTOK_TIME;
|
||||
{PIPE} return FWTOK_PIPE;
|
||||
{INT} yylval->intval = atoi(yytext);return FWTOK_INT;
|
||||
{FLOAT} yylval->floatval = atof(yytext);return FWTOK_FLOAT;
|
||||
{QSTR} yylval->strval = yytext;return FWTOK_QUOTEDSTR;
|
||||
{BTSTR} yylval->strval = yytext;return FWTOK_BTSTR;
|
||||
{STR} yylval->strval = yytext;return FWTOK_STR;
|
||||
{RULENAME} yylval->strval = yytext;return FWTOK_RULENAME;
|
||||
{SPACE} ;
|
||||
|
||||
%%
|
||||
@ -80,7 +80,6 @@
|
||||
#include <query_classifier.h>
|
||||
#include <spinlock.h>
|
||||
#include <session.h>
|
||||
#include <plugin.h>
|
||||
#include <housekeeper.h>
|
||||
|
||||
MODULE_INFO info =
|
||||
|
||||
@ -85,7 +85,6 @@ typedef struct
|
||||
char *user; /* User name to restrict matches */
|
||||
char *match; /* Regular expression to match */
|
||||
char *server; /* Server to route to */
|
||||
int cflags; /* Regexec compile flags */
|
||||
regex_t re; /* Compiled regex text */
|
||||
} REGEXHINT_INSTANCE;
|
||||
|
||||
@ -147,14 +146,17 @@ static FILTER *
|
||||
createInstance(char **options, FILTER_PARAMETER **params)
|
||||
{
|
||||
REGEXHINT_INSTANCE *my_instance;
|
||||
int i, cflags = REG_ICASE;
|
||||
int cflags = REG_ICASE;
|
||||
|
||||
if ((my_instance = calloc(1, sizeof(REGEXHINT_INSTANCE))) != NULL)
|
||||
if ((my_instance = malloc(sizeof(REGEXHINT_INSTANCE))) != NULL)
|
||||
{
|
||||
my_instance->match = NULL;
|
||||
my_instance->server = NULL;
|
||||
my_instance->source = NULL;
|
||||
my_instance->user = NULL;
|
||||
bool error = false;
|
||||
|
||||
for (i = 0; params && params[i]; i++)
|
||||
for (int i = 0; params && params[i]; i++)
|
||||
{
|
||||
if (!strcmp(params[i]->name, "match"))
|
||||
{
|
||||
@ -176,12 +178,13 @@ createInstance(char **options, FILTER_PARAMETER **params)
|
||||
{
|
||||
MXS_ERROR("namedserverfilter: Unexpected parameter '%s'.",
|
||||
params[i]->name);
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (options)
|
||||
{
|
||||
for (i = 0; options[i]; i++)
|
||||
for (int i = 0; options[i]; i++)
|
||||
{
|
||||
if (!strcasecmp(options[i], "ignorecase"))
|
||||
{
|
||||
@ -191,34 +194,54 @@ createInstance(char **options, FILTER_PARAMETER **params)
|
||||
{
|
||||
cflags &= ~REG_ICASE;
|
||||
}
|
||||
else if (!strcasecmp(options[i], "extended"))
|
||||
{
|
||||
cflags |= REG_EXTENDED;
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("namedserverfilter: unsupported option '%s'.",
|
||||
MXS_ERROR("namedserverfilter: Unsupported option '%s'.",
|
||||
options[i]);
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
my_instance->cflags = cflags;
|
||||
|
||||
if (my_instance->match == NULL || my_instance->server == NULL)
|
||||
if (my_instance->match == NULL)
|
||||
{
|
||||
MXS_ERROR("namedserverfilter: Missing required configured"
|
||||
" option. You must specify a match and server "
|
||||
"option as a minimum.");
|
||||
free(my_instance);
|
||||
return NULL;
|
||||
MXS_ERROR("namedserverfilter: Missing required parameters 'match'.");
|
||||
error = true;
|
||||
}
|
||||
|
||||
if (regcomp(&my_instance->re, my_instance->match,
|
||||
my_instance->cflags))
|
||||
if (my_instance->server == NULL)
|
||||
{
|
||||
MXS_ERROR("namedserverfilter: Missing required parameters 'server'.");
|
||||
error = true;
|
||||
}
|
||||
if (my_instance->server && my_instance->match &&
|
||||
regcomp(&my_instance->re, my_instance->match, cflags))
|
||||
{
|
||||
MXS_ERROR("namedserverfilter: Invalid regular expression '%s'.\n",
|
||||
my_instance->match);
|
||||
free(my_instance->match);
|
||||
free(my_instance->server);
|
||||
free(my_instance);
|
||||
return NULL;
|
||||
my_instance->match = NULL;
|
||||
error = true;
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (my_instance->match)
|
||||
{
|
||||
regfree(&my_instance->re);
|
||||
free(my_instance->match);
|
||||
}
|
||||
free(my_instance->server);
|
||||
free(my_instance->source);
|
||||
free(my_instance->user);
|
||||
free(my_instance);
|
||||
my_instance = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
return(FILTER *) my_instance;
|
||||
}
|
||||
|
||||
@ -175,20 +175,15 @@ createInstance(char **options, FILTER_PARAMETER **params)
|
||||
QLA_INSTANCE *my_instance;
|
||||
int i;
|
||||
|
||||
if ((my_instance = calloc(1, sizeof(QLA_INSTANCE))) != NULL)
|
||||
if ((my_instance = malloc(sizeof(QLA_INSTANCE))) != NULL)
|
||||
{
|
||||
if (options)
|
||||
{
|
||||
my_instance->filebase = strdup(options[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
my_instance->filebase = strdup("qla");
|
||||
}
|
||||
my_instance->source = NULL;
|
||||
my_instance->userName = NULL;
|
||||
my_instance->match = NULL;
|
||||
my_instance->nomatch = NULL;
|
||||
my_instance->filebase = NULL;
|
||||
bool error = false;
|
||||
|
||||
if (params)
|
||||
{
|
||||
for (i = 0; params[i]; i++)
|
||||
@ -211,55 +206,90 @@ createInstance(char **options, FILTER_PARAMETER **params)
|
||||
}
|
||||
else if (!strcmp(params[i]->name, "filebase"))
|
||||
{
|
||||
if (my_instance->filebase)
|
||||
{
|
||||
free(my_instance->filebase);
|
||||
my_instance->filebase = NULL;
|
||||
}
|
||||
my_instance->filebase = strdup(params[i]->value);
|
||||
}
|
||||
else if (!filter_standard_parameter(params[i]->name))
|
||||
{
|
||||
MXS_ERROR("qlafilter: Unexpected parameter '%s'.",
|
||||
params[i]->name);
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int cflags = REG_ICASE;
|
||||
|
||||
if (options)
|
||||
{
|
||||
for (i = 0; options[i]; i++)
|
||||
{
|
||||
if (!strcasecmp(options[i], "ignorecase"))
|
||||
{
|
||||
cflags |= REG_ICASE;
|
||||
}
|
||||
else if (!strcasecmp(options[i], "case"))
|
||||
{
|
||||
cflags &= ~REG_ICASE;
|
||||
}
|
||||
else if (!strcasecmp(options[i], "extended"))
|
||||
{
|
||||
cflags |= REG_EXTENDED;
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("qlafilter: Unsupported option '%s'.",
|
||||
options[i]);
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (my_instance->filebase == NULL)
|
||||
{
|
||||
MXS_ERROR("qlafilter: No 'filebase' parameter defined.");
|
||||
error = true;
|
||||
}
|
||||
|
||||
my_instance->sessions = 0;
|
||||
if (my_instance->match &&
|
||||
regcomp(&my_instance->re, my_instance->match, REG_ICASE))
|
||||
regcomp(&my_instance->re, my_instance->match, cflags))
|
||||
{
|
||||
MXS_ERROR("qlafilter: Invalid regular expression '%s'"
|
||||
" for the match parameter.\n",
|
||||
" for the 'match' parameter.\n",
|
||||
my_instance->match);
|
||||
free(my_instance->match);
|
||||
free(my_instance->source);
|
||||
if (my_instance->filebase)
|
||||
{
|
||||
free(my_instance->filebase);
|
||||
}
|
||||
free(my_instance);
|
||||
return NULL;
|
||||
my_instance->match = NULL;
|
||||
error = true;
|
||||
}
|
||||
if (my_instance->nomatch &&
|
||||
regcomp(&my_instance->nore, my_instance->nomatch,
|
||||
REG_ICASE))
|
||||
regcomp(&my_instance->nore, my_instance->nomatch, cflags))
|
||||
{
|
||||
MXS_ERROR("qlafilter: Invalid regular expression '%s'"
|
||||
" for the nomatch paramter.",
|
||||
my_instance->match);
|
||||
" for the 'nomatch' parameter.",
|
||||
my_instance->nomatch);
|
||||
free(my_instance->nomatch);
|
||||
my_instance->nomatch = NULL;
|
||||
error = true;
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (my_instance->match)
|
||||
{
|
||||
free(my_instance->match);
|
||||
regfree(&my_instance->re);
|
||||
}
|
||||
free(my_instance->match);
|
||||
free(my_instance->source);
|
||||
if (my_instance->filebase)
|
||||
|
||||
if (my_instance->match)
|
||||
{
|
||||
free(my_instance->filebase);
|
||||
free(my_instance->match);
|
||||
regfree(&my_instance->re);
|
||||
}
|
||||
free(my_instance->filebase);
|
||||
free(my_instance->source);
|
||||
free(my_instance->userName);
|
||||
free(my_instance);
|
||||
return NULL;
|
||||
my_instance = NULL;
|
||||
}
|
||||
}
|
||||
return(FILTER *) my_instance;
|
||||
|
||||
@ -407,6 +407,33 @@ createInstance(char **options, FILTER_PARAMETER **params)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int cflags = REG_ICASE;
|
||||
|
||||
if (options)
|
||||
{
|
||||
for (i = 0; options[i]; i++)
|
||||
{
|
||||
if (!strcasecmp(options[i], "ignorecase"))
|
||||
{
|
||||
cflags |= REG_ICASE;
|
||||
}
|
||||
else if (!strcasecmp(options[i], "case"))
|
||||
{
|
||||
cflags &= ~REG_ICASE;
|
||||
}
|
||||
else if (!strcasecmp(options[i], "extended"))
|
||||
{
|
||||
cflags |= REG_EXTENDED;
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("tee: unsupported option '%s'.",
|
||||
options[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (my_instance->service == NULL)
|
||||
{
|
||||
free(my_instance->match);
|
||||
@ -416,7 +443,7 @@ createInstance(char **options, FILTER_PARAMETER **params)
|
||||
}
|
||||
|
||||
if (my_instance->match &&
|
||||
regcomp(&my_instance->re, my_instance->match, REG_ICASE))
|
||||
regcomp(&my_instance->re, my_instance->match, cflags))
|
||||
{
|
||||
MXS_ERROR("tee: Invalid regular expression '%s'"
|
||||
" for the match parameter.",
|
||||
@ -427,8 +454,7 @@ createInstance(char **options, FILTER_PARAMETER **params)
|
||||
return NULL;
|
||||
}
|
||||
if (my_instance->nomatch &&
|
||||
regcomp(&my_instance->nore, my_instance->nomatch,
|
||||
REG_ICASE))
|
||||
regcomp(&my_instance->nore, my_instance->nomatch, cflags))
|
||||
{
|
||||
MXS_ERROR("tee: Invalid regular expression '%s'"
|
||||
" for the nomatch paramter.\n",
|
||||
|
||||
@ -176,7 +176,6 @@ GetModuleObject()
|
||||
{
|
||||
return &MyObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of the filter for a particular service
|
||||
* within MaxScale.
|
||||
@ -192,14 +191,16 @@ createInstance(char **options, FILTER_PARAMETER **params)
|
||||
int i;
|
||||
TOPN_INSTANCE *my_instance;
|
||||
|
||||
if ((my_instance = calloc(1, sizeof(TOPN_INSTANCE))) != NULL)
|
||||
if ((my_instance = malloc(sizeof(TOPN_INSTANCE))) != NULL)
|
||||
{
|
||||
my_instance->topN = 10;
|
||||
my_instance->match = NULL;
|
||||
my_instance->exclude = NULL;
|
||||
my_instance->source = NULL;
|
||||
my_instance->user = NULL;
|
||||
my_instance->filebase = strdup("top");
|
||||
my_instance->filebase = NULL;
|
||||
bool error = false;
|
||||
|
||||
for (i = 0; params && params[i]; i++)
|
||||
{
|
||||
if (!strcmp(params[i]->name, "count"))
|
||||
@ -208,7 +209,6 @@ createInstance(char **options, FILTER_PARAMETER **params)
|
||||
}
|
||||
else if (!strcmp(params[i]->name, "filebase"))
|
||||
{
|
||||
free(my_instance->filebase);
|
||||
my_instance->filebase = strdup(params[i]->value);
|
||||
}
|
||||
else if (!strcmp(params[i]->name, "match"))
|
||||
@ -231,41 +231,84 @@ createInstance(char **options, FILTER_PARAMETER **params)
|
||||
{
|
||||
MXS_ERROR("topfilter: Unexpected parameter '%s'.",
|
||||
params[i]->name);
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
|
||||
int cflags = REG_ICASE;
|
||||
|
||||
if (options)
|
||||
{
|
||||
MXS_ERROR("topfilter: Options are not supported by this "
|
||||
" filter. They will be ignored.");
|
||||
for (i = 0; options[i]; i++)
|
||||
{
|
||||
if (!strcasecmp(options[i], "ignorecase"))
|
||||
{
|
||||
cflags |= REG_ICASE;
|
||||
}
|
||||
else if (!strcasecmp(options[i], "case"))
|
||||
{
|
||||
cflags &= ~REG_ICASE;
|
||||
}
|
||||
else if (!strcasecmp(options[i], "extended"))
|
||||
{
|
||||
cflags |= REG_EXTENDED;
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("topfilter: Unsupported option '%s'.",
|
||||
options[i]);
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (my_instance->filebase == NULL)
|
||||
{
|
||||
MXS_ERROR("topfilter: No 'filebase' parameter defined.");
|
||||
error = true;
|
||||
}
|
||||
|
||||
my_instance->sessions = 0;
|
||||
if (my_instance->match &&
|
||||
regcomp(&my_instance->re, my_instance->match, REG_ICASE))
|
||||
regcomp(&my_instance->re, my_instance->match, cflags))
|
||||
{
|
||||
MXS_ERROR("topfilter: Invalid regular expression '%s'"
|
||||
" for the match parameter.",
|
||||
my_instance->match);
|
||||
free(my_instance->match);
|
||||
free(my_instance->source);
|
||||
free(my_instance->user);
|
||||
free(my_instance->filebase);
|
||||
free(my_instance);
|
||||
return NULL;
|
||||
}
|
||||
if (my_instance->exclude &&
|
||||
regcomp(&my_instance->exre, my_instance->exclude,
|
||||
REG_ICASE))
|
||||
{
|
||||
MXS_ERROR("qlafilter: Invalid regular expression '%s'"
|
||||
" for the nomatch paramter.\n",
|
||||
" for the 'match' parameter.",
|
||||
my_instance->match);
|
||||
regfree(&my_instance->re);
|
||||
free(my_instance->match);
|
||||
my_instance->match = NULL;
|
||||
error = true;
|
||||
}
|
||||
if (my_instance->exclude &&
|
||||
regcomp(&my_instance->exre, my_instance->exclude, cflags))
|
||||
{
|
||||
MXS_ERROR("topfilter: Invalid regular expression '%s'"
|
||||
" for the 'nomatch' parameter.\n",
|
||||
my_instance->exclude);
|
||||
regfree(&my_instance->exre);
|
||||
free(my_instance->exclude);
|
||||
my_instance->exclude = NULL;
|
||||
error = true;
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (my_instance->exclude)
|
||||
{
|
||||
regfree(&my_instance->exre);
|
||||
free(my_instance->exclude);
|
||||
}
|
||||
if (my_instance->match)
|
||||
{
|
||||
regfree(&my_instance->re);
|
||||
free(my_instance->match);
|
||||
}
|
||||
free(my_instance->filebase);
|
||||
free(my_instance->source);
|
||||
free(my_instance->user);
|
||||
free(my_instance->filebase);
|
||||
free(my_instance);
|
||||
return NULL;
|
||||
my_instance = NULL;
|
||||
}
|
||||
}
|
||||
return(FILTER *) my_instance;
|
||||
|
||||
Reference in New Issue
Block a user