From 6067c21c1b5ddd9a9da61a40ae55edd063704bee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 4 Sep 2017 15:23:11 +0300 Subject: [PATCH] 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. --- include/maxscale/filter.hh | 12 +- .../modules/filter/dbfwfilter/dbfwfilter.cc | 157 ++---------------- .../modules/filter/dbfwfilter/dbfwfilter.hh | 96 ++++++----- 3 files changed, 80 insertions(+), 185 deletions(-) diff --git a/include/maxscale/filter.hh b/include/maxscale/filter.hh index b39c63873..f711ae589 100644 --- a/include/maxscale/filter.hh +++ b/include/maxscale/filter.hh @@ -170,7 +170,7 @@ protected: * An instantiation of the Filter template is used for creating a filter. * Filter is an example of the "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: * @@ -183,11 +183,19 @@ protected: * class MyFilter : public maxscale::Filter * { * public: + * // This creates a new filter instance * 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); * - * 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(); * }; * @endcode diff --git a/server/modules/filter/dbfwfilter/dbfwfilter.cc b/server/modules/filter/dbfwfilter/dbfwfilter.cc index 20c44ae49..6fd02917b 100644 --- a/server/modules/filter/dbfwfilter/dbfwfilter.cc +++ b/server/modules/filter/dbfwfilter/dbfwfilter.cc @@ -92,19 +92,6 @@ int dbfw_yyparse(void*); #endif 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 */ thread_local struct { @@ -504,22 +491,6 @@ MXS_MODULE* MXS_CREATE_MODULE() dbfw_show_rules_json, 1, args_rules_show_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 = { MXS_MODULE_API_FILTER, @@ -528,7 +499,7 @@ MXS_MODULE* MXS_CREATE_MODULE() "Firewall Filter", "V1.2.0", RCAP_TYPE_STMT_INPUT, - &MyObject, + &Dbfw::s_object, NULL, /* Process init. */ NULL, /* Process finish. */ 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; RuleList rules; 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; } +DbfwSession* Dbfw::newSession(MXS_SESSION* session) +{ + return new (std::nothrow) DbfwSession(this, session); +} + fw_actions Dbfw::get_action() const { return m_action; @@ -1181,75 +1157,6 @@ bool Dbfw::reload_rules() 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 * @@ -1315,6 +1222,7 @@ static std::string get_sql(GWBUF* buffer) } DbfwSession::DbfwSession(Dbfw* instance, MXS_SESSION* session): + mxs::FilterSession::FilterSession(session), m_instance(instance), m_session(session) { @@ -1469,7 +1377,7 @@ int DbfwSession::routeQuery(GWBUF* buffer) if (query_ok) { - rval = down.routeQuery(down.instance, down.session, buffer); + rval = mxs::FilterSession::routeQuery(buffer); } else { @@ -1677,30 +1585,6 @@ static bool update_rules(Dbfw* my_instance) 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 * @@ -1711,11 +1595,8 @@ routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWBUF *queue) * @param fsession Filter session, may be NULL * @param dcb The DCB for diagnostic output */ -static void -diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb) +void Dbfw::diagnostics(DCB *dcb) const { - Dbfw *my_instance = (Dbfw *) instance; - dcb_printf(dcb, "Firewall Filter\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 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); } - -/** - * Capability routine. - * - * @return The capabilities of the filter. - */ -static uint64_t getCapabilities(MXS_FILTER* instance) -{ - return RCAP_TYPE_NONE; -} diff --git a/server/modules/filter/dbfwfilter/dbfwfilter.hh b/server/modules/filter/dbfwfilter/dbfwfilter.hh index 6f2fb7f55..99fa9346e 100644 --- a/server/modules/filter/dbfwfilter/dbfwfilter.hh +++ b/server/modules/filter/dbfwfilter/dbfwfilter.hh @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include @@ -158,10 +158,45 @@ struct QuerySpeed bool active; /*< If the rule has been triggered */ }; +class Dbfw; +class User; +typedef std::tr1::shared_ptr 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. */ -class Dbfw +class Dbfw: public mxs::Filter { Dbfw(const Dbfw&); Dbfw& operator=(const Dbfw&); @@ -176,7 +211,16 @@ public: * * @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 @@ -217,6 +261,15 @@ public: bool reload_rules(std::string filename); bool reload_rules(); + /** Diagnostic routines */ + void diagnostics(DCB *dcb) const; + json_t* diagnostics_json() const; + + uint64_t getCapabilities() const + { + return RCAP_TYPE_NONE; + } + private: fw_actions m_action; /*< Default operation mode, defaults to deny */ int m_log_match; /*< Log matching and/or non-matching queries */ @@ -228,43 +281,6 @@ private: bool do_reload_rules(std::string filename); }; -class User; -typedef std::tr1::shared_ptr 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 std::list ValueList;