From 11a240cb15cea9b195bca167f63719e2e37b4a20 Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Wed, 15 Nov 2017 11:38:59 +0200 Subject: [PATCH] MXS-1519 Use fw instance specific rules and users The rules and users need to be distinct not only for each thread but for each instance and thread. --- .../modules/filter/dbfwfilter/dbfwfilter.cc | 62 ++++++++++++------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/server/modules/filter/dbfwfilter/dbfwfilter.cc b/server/modules/filter/dbfwfilter/dbfwfilter.cc index cf9ab4c3a..f87e09177 100644 --- a/server/modules/filter/dbfwfilter/dbfwfilter.cc +++ b/server/modules/filter/dbfwfilter/dbfwfilter.cc @@ -67,6 +67,7 @@ #include #include #include +#include #include #include @@ -97,16 +98,27 @@ namespace { /** The rules and users for each thread */ -struct DbfwThread +class DbfwThread { - DbfwThread(): - rule_version(0) - { - } +public: + int& rule_version(const Dbfw* d) { return m_instance_data[d].rule_version; } + RuleList& rules(const Dbfw* d) { return m_instance_data[d].rules; } + UserMap& users(const Dbfw* d) { return m_instance_data[d].users; } - int rule_version; - RuleList rules; - UserMap users; +private: + class Data + { + public: + Data() + : rule_version(0) + {} + + int rule_version; + RuleList rules; + UserMap users; + }; + + std::map m_instance_data; }; thread_local DbfwThread* this_thread = NULL; @@ -140,7 +152,7 @@ static json_t* rules_to_json(const RuleList& rules) { json_t* rval = json_array(); - for (RuleList::const_iterator it = this_thread->rules.begin(); it != this_thread->rules.end(); it++) + for (RuleList::const_iterator it = rules.begin(); it != rules.end(); it++) { const SRule& rule = *it; json_array_append_new(rval, rule_to_json(rule)); @@ -410,7 +422,10 @@ bool dbfw_show_rules(const MODULECMD_ARG *argv, json_t** output) dcb_printf(dcb, "Rule, Type, Times Matched\n"); - if (this_thread->rules.empty() || this_thread->users.empty()) + RuleList& rules = this_thread->rules(inst); + UserMap& users = this_thread->users(inst); + + if (rules.empty() || users.empty()) { if (!replace_rules(inst)) { @@ -418,7 +433,7 @@ bool dbfw_show_rules(const MODULECMD_ARG *argv, json_t** output) } } - for (RuleList::const_iterator it = this_thread->rules.begin(); it != this_thread->rules.end(); it++) + for (RuleList::const_iterator it = rules.begin(); it != rules.end(); it++) { const SRule& rule = *it; char buf[rule->name().length() + 200]; // Some extra space @@ -436,7 +451,10 @@ bool dbfw_show_rules_json(const MODULECMD_ARG *argv, json_t** output) json_t* arr = json_array(); - if (this_thread->rules.empty() || this_thread->users.empty()) + RuleList& rules = this_thread->rules(inst); + UserMap& users = this_thread->users(inst); + + if (rules.empty() || users.empty()) { if (!replace_rules(inst)) { @@ -444,7 +462,7 @@ bool dbfw_show_rules_json(const MODULECMD_ARG *argv, json_t** output) } } - for (RuleList::const_iterator it = this_thread->rules.begin(); it != this_thread->rules.end(); it++) + for (RuleList::const_iterator it = rules.begin(); it != rules.end(); it++) { const SRule& rule = *it; json_array_append_new(arr, rule_to_json(rule)); @@ -1092,11 +1110,11 @@ bool replace_rules(Dbfw* instance) if (process_rule_file(filename, &rules, &users)) { - this_thread->rules.swap(rules); - this_thread->users.swap(users); + this_thread->rules(instance).swap(rules); + this_thread->users(instance).swap(users); rval = true; } - else if (!this_thread->rules.empty() && !this_thread->users.empty()) + else if (!this_thread->rules(instance).empty() && !this_thread->users(instance).empty()) { MXS_ERROR("Failed to parse rules at '%s'. Old rules are still used.", filename.c_str()); @@ -1116,14 +1134,14 @@ static bool update_rules(Dbfw* my_instance) bool rval = true; int rule_version = my_instance->get_rule_version(); - if (this_thread->rule_version < rule_version) + if (this_thread->rule_version(my_instance) < rule_version) { if (!replace_rules(my_instance)) { rval = false; } - this_thread->rule_version = rule_version; + this_thread->rule_version(my_instance) = rule_version; } return rval; @@ -1409,7 +1427,7 @@ int DbfwSession::routeQuery(GWBUF* buffer) ss_dassert(analyzed_queue); } - SUser suser = find_user_data(this_thread->users, user(), remote()); + SUser suser = find_user_data(this_thread->users(m_instance), user(), remote()); bool query_ok = false; if (command_is_mandatory(buffer)) @@ -1673,7 +1691,9 @@ void Dbfw::diagnostics(DCB *dcb) const dcb_printf(dcb, "Firewall Filter\n"); dcb_printf(dcb, "Rule, Type, Times Matched\n"); - for (RuleList::const_iterator it = this_thread->rules.begin(); it != this_thread->rules.end(); it++) + RuleList& rules = this_thread->rules(this); + + for (RuleList::const_iterator it = rules.begin(); it != rules.end(); it++) { const SRule& rule = *it; char buf[rule->name().length() + 200]; @@ -1694,5 +1714,5 @@ void Dbfw::diagnostics(DCB *dcb) const */ json_t* Dbfw::diagnostics_json() const { - return rules_to_json(this_thread->rules); + return rules_to_json(this_thread->rules(this)); }