MXS-1346: Use the filter template in dbfwfilter
The dbfwfilter now uses the MaxScale filter template. Also fixed up some of the filter template documentation.
This commit is contained in:
@ -170,7 +170,7 @@ protected:
|
|||||||
* An instantiation of the Filter template is used for creating a filter.
|
* An instantiation of the Filter template is used for creating a filter.
|
||||||
* Filter is an example of the "Curiously recurring template pattern"
|
* Filter is an example of the "Curiously recurring template pattern"
|
||||||
* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
|
* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
|
||||||
* that is used for compile time polymorfism.
|
* that is used for compile time polymorphism.
|
||||||
*
|
*
|
||||||
* The typical way for using the template is as follows:
|
* The typical way for using the template is as follows:
|
||||||
*
|
*
|
||||||
@ -183,11 +183,19 @@ protected:
|
|||||||
* class MyFilter : public maxscale::Filter<MyFilter, MyFilterSession>
|
* class MyFilter : public maxscale::Filter<MyFilter, MyFilterSession>
|
||||||
* {
|
* {
|
||||||
* public:
|
* public:
|
||||||
|
* // This creates a new filter instance
|
||||||
* static MyFilter* create(const char* zName, char** pzOptions, MXS_CONFIG_PARAMETER* ppParams);
|
* static MyFilter* create(const char* zName, char** pzOptions, MXS_CONFIG_PARAMETER* ppParams);
|
||||||
*
|
*
|
||||||
|
* // This creates a new session for a filter instance
|
||||||
* MyFilterSession* newSession(MXS_SESSION* pSession);
|
* MyFilterSession* newSession(MXS_SESSION* pSession);
|
||||||
*
|
*
|
||||||
* void diagnostics(DCB* pDcb);
|
* // Diagnostic function that prints to a DCB
|
||||||
|
* void diagnostics(DCB* pDcb) const;
|
||||||
|
*
|
||||||
|
* // Diagnostic function that returns a JSON object
|
||||||
|
* json_t* diagnostics_json() const;
|
||||||
|
*
|
||||||
|
* // Get filter capabilities
|
||||||
* uint64_t getCapabilities();
|
* uint64_t getCapabilities();
|
||||||
* };
|
* };
|
||||||
* @endcode
|
* @endcode
|
||||||
|
@ -92,19 +92,6 @@ int dbfw_yyparse(void*);
|
|||||||
#endif
|
#endif
|
||||||
MXS_END_DECLS
|
MXS_END_DECLS
|
||||||
|
|
||||||
/*
|
|
||||||
* The filter entry points
|
|
||||||
*/
|
|
||||||
static MXS_FILTER *createInstance(const char *name, char **options, MXS_CONFIG_PARAMETER *);
|
|
||||||
static MXS_FILTER_SESSION *newSession(MXS_FILTER *instance, MXS_SESSION *session);
|
|
||||||
static void closeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
|
|
||||||
static void freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
|
|
||||||
static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream);
|
|
||||||
static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
|
|
||||||
static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb);
|
|
||||||
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
|
|
||||||
static uint64_t getCapabilities(MXS_FILTER* instance);
|
|
||||||
|
|
||||||
/** The rules and users for each thread */
|
/** The rules and users for each thread */
|
||||||
thread_local struct
|
thread_local struct
|
||||||
{
|
{
|
||||||
@ -504,22 +491,6 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
|||||||
dbfw_show_rules_json, 1, args_rules_show_json,
|
dbfw_show_rules_json, 1, args_rules_show_json,
|
||||||
"Show dbfwfilter rule statistics as JSON");
|
"Show dbfwfilter rule statistics as JSON");
|
||||||
|
|
||||||
static MXS_FILTER_OBJECT MyObject =
|
|
||||||
{
|
|
||||||
createInstance,
|
|
||||||
newSession,
|
|
||||||
closeSession,
|
|
||||||
freeSession,
|
|
||||||
setDownstream,
|
|
||||||
NULL, // No setUpStream
|
|
||||||
routeQuery,
|
|
||||||
NULL, // No clientReply
|
|
||||||
diagnostic,
|
|
||||||
diagnostic_json,
|
|
||||||
getCapabilities,
|
|
||||||
NULL, // No destroyInstance
|
|
||||||
};
|
|
||||||
|
|
||||||
static MXS_MODULE info =
|
static MXS_MODULE info =
|
||||||
{
|
{
|
||||||
MXS_MODULE_API_FILTER,
|
MXS_MODULE_API_FILTER,
|
||||||
@ -528,7 +499,7 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
|||||||
"Firewall Filter",
|
"Firewall Filter",
|
||||||
"V1.2.0",
|
"V1.2.0",
|
||||||
RCAP_TYPE_STMT_INPUT,
|
RCAP_TYPE_STMT_INPUT,
|
||||||
&MyObject,
|
&Dbfw::s_object,
|
||||||
NULL, /* Process init. */
|
NULL, /* Process init. */
|
||||||
NULL, /* Process finish. */
|
NULL, /* Process finish. */
|
||||||
NULL, /* Thread init. */
|
NULL, /* Thread init. */
|
||||||
@ -1103,21 +1074,26 @@ Dbfw::~Dbfw()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Dbfw* Dbfw::create(MXS_CONFIG_PARAMETER* params)
|
Dbfw* Dbfw::create(const char* zName, char** pzOptions, MXS_CONFIG_PARAMETER* pParams)
|
||||||
{
|
{
|
||||||
Dbfw* rval = NULL;
|
Dbfw* rval = NULL;
|
||||||
RuleList rules;
|
RuleList rules;
|
||||||
UserMap users;
|
UserMap users;
|
||||||
std::string file = config_get_string(params, "rules");
|
std::string file = config_get_string(pParams, "rules");
|
||||||
|
|
||||||
if (!process_rule_file(file, &rules, &users))
|
if (process_rule_file(file, &rules, &users))
|
||||||
{
|
{
|
||||||
rval = new (std::nothrow) Dbfw(params);
|
rval = new (std::nothrow) Dbfw(pParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DbfwSession* Dbfw::newSession(MXS_SESSION* session)
|
||||||
|
{
|
||||||
|
return new (std::nothrow) DbfwSession(this, session);
|
||||||
|
}
|
||||||
|
|
||||||
fw_actions Dbfw::get_action() const
|
fw_actions Dbfw::get_action() const
|
||||||
{
|
{
|
||||||
return m_action;
|
return m_action;
|
||||||
@ -1181,75 +1157,6 @@ bool Dbfw::reload_rules()
|
|||||||
return do_reload_rules(m_filename);
|
return do_reload_rules(m_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an instance of the filter for a particular service
|
|
||||||
* within MaxScale.
|
|
||||||
*
|
|
||||||
* @param name The name of the instance (as defined in the config file).
|
|
||||||
* @param options The options for this filter
|
|
||||||
* @param params The array of name/value pair parameters for the filter
|
|
||||||
*
|
|
||||||
* @return The instance data for this new instance
|
|
||||||
*/
|
|
||||||
static MXS_FILTER *
|
|
||||||
createInstance(const char *name, char **options, MXS_CONFIG_PARAMETER *params)
|
|
||||||
{
|
|
||||||
return (MXS_FILTER *) Dbfw::create(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Associate a new session with this instance of the filter.
|
|
||||||
*
|
|
||||||
* @param instance The filter instance data
|
|
||||||
* @param session The session itself
|
|
||||||
* @return Session specific data for this session
|
|
||||||
*/
|
|
||||||
static MXS_FILTER_SESSION* newSession(MXS_FILTER *instance, MXS_SESSION *session)
|
|
||||||
{
|
|
||||||
Dbfw *my_instance = (Dbfw*)instance;
|
|
||||||
return (MXS_FILTER_SESSION*)new (std::nothrow) DbfwSession(my_instance, session);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close a session with the filter, this is the mechanism
|
|
||||||
* by which a filter may cleanup data structure etc.
|
|
||||||
*
|
|
||||||
* @param instance The filter instance data
|
|
||||||
* @param session The session being closed
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
closeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Free the memory associated with the session
|
|
||||||
*
|
|
||||||
* @param instance The filter instance
|
|
||||||
* @param session The filter session
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session)
|
|
||||||
{
|
|
||||||
DbfwSession *my_session = (DbfwSession*)session;
|
|
||||||
delete my_session;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the downstream filter or router to which queries will be
|
|
||||||
* passed from this filter.
|
|
||||||
*
|
|
||||||
* @param instance The filter instance data
|
|
||||||
* @param session The filter session
|
|
||||||
* @param downstream The downstream filter or router.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *session, MXS_DOWNSTREAM *downstream)
|
|
||||||
{
|
|
||||||
DbfwSession *my_session = (DbfwSession *) session;
|
|
||||||
my_session->down = *downstream;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the user specific data for this session
|
* Retrieve the user specific data for this session
|
||||||
*
|
*
|
||||||
@ -1315,6 +1222,7 @@ static std::string get_sql(GWBUF* buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DbfwSession::DbfwSession(Dbfw* instance, MXS_SESSION* session):
|
DbfwSession::DbfwSession(Dbfw* instance, MXS_SESSION* session):
|
||||||
|
mxs::FilterSession::FilterSession(session),
|
||||||
m_instance(instance),
|
m_instance(instance),
|
||||||
m_session(session)
|
m_session(session)
|
||||||
{
|
{
|
||||||
@ -1469,7 +1377,7 @@ int DbfwSession::routeQuery(GWBUF* buffer)
|
|||||||
|
|
||||||
if (query_ok)
|
if (query_ok)
|
||||||
{
|
{
|
||||||
rval = down.routeQuery(down.instance, down.session, buffer);
|
rval = mxs::FilterSession::routeQuery(buffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1677,30 +1585,6 @@ static bool update_rules(Dbfw* my_instance)
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The routeQuery entry point. This is passed the query buffer
|
|
||||||
* to which the filter should be applied. Once processed the
|
|
||||||
* query is passed to the downstream component
|
|
||||||
* (filter or router) in the filter chain.
|
|
||||||
*
|
|
||||||
* @param instance The filter instance data
|
|
||||||
* @param session The filter session
|
|
||||||
* @param queue The query data
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWBUF *queue)
|
|
||||||
{
|
|
||||||
Dbfw *my_instance = (Dbfw *) instance;
|
|
||||||
|
|
||||||
if (!update_rules(my_instance))
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DbfwSession *my_session = (DbfwSession *) session;
|
|
||||||
return my_session->routeQuery(queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Diagnostics routine
|
* Diagnostics routine
|
||||||
*
|
*
|
||||||
@ -1711,11 +1595,8 @@ routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWBUF *queue)
|
|||||||
* @param fsession Filter session, may be NULL
|
* @param fsession Filter session, may be NULL
|
||||||
* @param dcb The DCB for diagnostic output
|
* @param dcb The DCB for diagnostic output
|
||||||
*/
|
*/
|
||||||
static void
|
void Dbfw::diagnostics(DCB *dcb) const
|
||||||
diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb)
|
|
||||||
{
|
{
|
||||||
Dbfw *my_instance = (Dbfw *) instance;
|
|
||||||
|
|
||||||
dcb_printf(dcb, "Firewall Filter\n");
|
dcb_printf(dcb, "Firewall Filter\n");
|
||||||
dcb_printf(dcb, "Rule, Type, Times Matched\n");
|
dcb_printf(dcb, "Rule, Type, Times Matched\n");
|
||||||
|
|
||||||
@ -1738,17 +1619,7 @@ diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb)
|
|||||||
* @param fsession Filter session, may be NULL
|
* @param fsession Filter session, may be NULL
|
||||||
* @param dcb The DCB for diagnostic output
|
* @param dcb The DCB for diagnostic output
|
||||||
*/
|
*/
|
||||||
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
|
json_t* Dbfw::diagnostics_json() const
|
||||||
{
|
{
|
||||||
return rules_to_json(this_thread.rules);
|
return rules_to_json(this_thread.rules);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Capability routine.
|
|
||||||
*
|
|
||||||
* @return The capabilities of the filter.
|
|
||||||
*/
|
|
||||||
static uint64_t getCapabilities(MXS_FILTER* instance)
|
|
||||||
{
|
|
||||||
return RCAP_TYPE_NONE;
|
|
||||||
}
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
#include <tr1/memory>
|
#include <tr1/memory>
|
||||||
#include <tr1/unordered_map>
|
#include <tr1/unordered_map>
|
||||||
|
|
||||||
#include <maxscale/filter.h>
|
#include <maxscale/filter.hh>
|
||||||
#include <maxscale/query_classifier.h>
|
#include <maxscale/query_classifier.h>
|
||||||
#include <maxscale/spinlock.h>
|
#include <maxscale/spinlock.h>
|
||||||
|
|
||||||
@ -158,10 +158,45 @@ struct QuerySpeed
|
|||||||
bool active; /*< If the rule has been triggered */
|
bool active; /*< If the rule has been triggered */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Dbfw;
|
||||||
|
class User;
|
||||||
|
typedef std::tr1::shared_ptr<User> SUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The session structure for Firewall filter.
|
||||||
|
*/
|
||||||
|
class DbfwSession: public mxs::FilterSession
|
||||||
|
{
|
||||||
|
DbfwSession(const DbfwSession&);
|
||||||
|
DbfwSession& operator=(const DbfwSession&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
DbfwSession(Dbfw* instance, MXS_SESSION* session);
|
||||||
|
~DbfwSession();
|
||||||
|
|
||||||
|
void set_error(std::string error);
|
||||||
|
std::string get_error() const;
|
||||||
|
void clear_error();
|
||||||
|
int send_error();
|
||||||
|
|
||||||
|
std::string user() const;
|
||||||
|
std::string remote() const;
|
||||||
|
|
||||||
|
int routeQuery(GWBUF* query);
|
||||||
|
QuerySpeed* query_speed(); // TODO: Remove this, it exposes internals to a Rule
|
||||||
|
fw_actions get_action() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Dbfw *m_instance; /*< Router instance */
|
||||||
|
MXS_SESSION *m_session; /*< Client session structure */
|
||||||
|
std::string m_error; /*< Rule specific error message */
|
||||||
|
QuerySpeed m_qs; /*< How fast the user has executed queries */
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Firewall filter instance.
|
* The Firewall filter instance.
|
||||||
*/
|
*/
|
||||||
class Dbfw
|
class Dbfw: public mxs::Filter<Dbfw, DbfwSession>
|
||||||
{
|
{
|
||||||
Dbfw(const Dbfw&);
|
Dbfw(const Dbfw&);
|
||||||
Dbfw& operator=(const Dbfw&);
|
Dbfw& operator=(const Dbfw&);
|
||||||
@ -176,7 +211,16 @@ public:
|
|||||||
*
|
*
|
||||||
* @return New instance or NULL on error
|
* @return New instance or NULL on error
|
||||||
*/
|
*/
|
||||||
static Dbfw* create(MXS_CONFIG_PARAMETER* params);
|
static Dbfw* create(const char* zName, char** pzOptions, MXS_CONFIG_PARAMETER* ppParams);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new filter session
|
||||||
|
*
|
||||||
|
* @param session Session object
|
||||||
|
*
|
||||||
|
* @return New session or NULL on error
|
||||||
|
*/
|
||||||
|
DbfwSession* newSession(MXS_SESSION* session);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the action mode of this instance
|
* Get the action mode of this instance
|
||||||
@ -217,6 +261,15 @@ public:
|
|||||||
bool reload_rules(std::string filename);
|
bool reload_rules(std::string filename);
|
||||||
bool reload_rules();
|
bool reload_rules();
|
||||||
|
|
||||||
|
/** Diagnostic routines */
|
||||||
|
void diagnostics(DCB *dcb) const;
|
||||||
|
json_t* diagnostics_json() const;
|
||||||
|
|
||||||
|
uint64_t getCapabilities() const
|
||||||
|
{
|
||||||
|
return RCAP_TYPE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
fw_actions m_action; /*< Default operation mode, defaults to deny */
|
fw_actions m_action; /*< Default operation mode, defaults to deny */
|
||||||
int m_log_match; /*< Log matching and/or non-matching queries */
|
int m_log_match; /*< Log matching and/or non-matching queries */
|
||||||
@ -228,43 +281,6 @@ private:
|
|||||||
bool do_reload_rules(std::string filename);
|
bool do_reload_rules(std::string filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
class User;
|
|
||||||
typedef std::tr1::shared_ptr<User> SUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The session structure for Firewall filter.
|
|
||||||
*/
|
|
||||||
class DbfwSession
|
|
||||||
{
|
|
||||||
DbfwSession(const DbfwSession&);
|
|
||||||
DbfwSession& operator=(const DbfwSession&);
|
|
||||||
|
|
||||||
public:
|
|
||||||
DbfwSession(Dbfw* instance, MXS_SESSION* session);
|
|
||||||
~DbfwSession();
|
|
||||||
|
|
||||||
void set_error(std::string error);
|
|
||||||
std::string get_error() const;
|
|
||||||
void clear_error();
|
|
||||||
int send_error();
|
|
||||||
|
|
||||||
std::string user() const;
|
|
||||||
std::string remote() const;
|
|
||||||
|
|
||||||
int routeQuery(GWBUF* query);
|
|
||||||
QuerySpeed* query_speed(); // TODO: Remove this, it exposes internals to a Rule
|
|
||||||
fw_actions get_action() const;
|
|
||||||
|
|
||||||
MXS_DOWNSTREAM down; /*< Next object in the downstream chain */
|
|
||||||
MXS_UPSTREAM up; /*< Next object in the upstream chain */
|
|
||||||
|
|
||||||
private:
|
|
||||||
Dbfw *m_instance; /*< Router instance */
|
|
||||||
MXS_SESSION *m_session; /*< Client session structure */
|
|
||||||
std::string m_error; /*< Rule specific error message */
|
|
||||||
QuerySpeed m_qs; /*< How fast the user has executed queries */
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Typedef for a list of strings */
|
/** Typedef for a list of strings */
|
||||||
typedef std::list<std::string> ValueList;
|
typedef std::list<std::string> ValueList;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user