diff --git a/src/filters/base.hpp b/src/filters/base.hpp index 00bb003d9f6c397498ba3acc7fbddc366eeade04..09a7d1a3a473572006b50e86d07bd093c328b6c0 100644 --- a/src/filters/base.hpp +++ b/src/filters/base.hpp @@ -30,7 +30,7 @@ namespace Filters { }; struct ChainedFilters : public BaseFilter { - ChainedFilters(const std::list<Filters::BaseFilter*>& chainedFilters) + explicit ChainedFilters(const std::list<Filters::BaseFilter*>& chainedFilters) : chainedFilters(chainedFilters) {} // Usually the encrypt/encode/obfs function. @@ -42,7 +42,7 @@ namespace Filters { } // Usually the decrypt/decode/de-obfs function. - virtual string convertBackward(string binaryDatagram) { + virtual string convertBackward(string binaryDatagram) override { for (auto iter = chainedFilters.rbegin(); iter != chainedFilters.rend(); ++iter) { binaryDatagram = (*iter)->convertForward(binaryDatagram); } @@ -51,6 +51,29 @@ namespace Filters { const std::list<Filters::BaseFilter*>& chainedFilters; }; + + struct ReversedFilter : public BaseFilter { + explicit ReversedFilter(BaseFilter* real, bool I_should_delete = false) : real(real), I_should_delete(I_should_delete) {} + + virtual ~ReversedFilter() { + if (I_should_delete) + delete real; + } + + // Usually the encrypt/encode/obfs function. + virtual string convertForward(string binaryDatagram) override { + return real->convertBackward(binaryDatagram); + } + + // Usually the decrypt/decode/de-obfs function. + virtual string convertBackward(string binaryDatagram) override { + return real->convertForward(binaryDatagram); + } + + bool I_should_delete = false; + BaseFilter* real; + }; + } #endif diff --git a/src/forwarder.hpp b/src/forwarder.hpp index 9dfaea3c24e393a0797d2c94bf8b1124c2feb825..584784bebe6a2b58b50460cd09fc40d73ff687d8 100644 --- a/src/forwarder.hpp +++ b/src/forwarder.hpp @@ -14,6 +14,23 @@ using std::string; +// This function parse the FilterConfig string for you. Register implemented modules here! +inline Filters::BaseFilter* CreateFilterFromConfig(rlib::string filterConfig) { + Filters::BaseFilter *newFilter = nullptr; + if (filterConfig.starts_with("aes@")) + newFilter = new Filters::AESFilter(); + else if (filterConfig.starts_with("xor@")) + newFilter = new Filters::XorFilter(); // these filters were not deleted. just a note. + else if (filterConfig.starts_with("reverse@")) { + auto newFilterConfig = filterConfig.substr(8); + newFilter = new Filters::ReversedFilter(CreateFilterFromConfig(newFilterConfig), true); + } + else + throw std::invalid_argument("Unknown filter in filterConfig item: " + filterConfig); + + newFilter->loadConfig(filterConfig); + return newFilter; +} class Forwarder { public: @@ -36,19 +53,8 @@ public: std::list<Filters::BaseFilter*> chainedFilters; - for (auto &&filterConfig : filterConfigs) { - Filters::BaseFilter *newFilter = nullptr; - if (filterConfig.starts_with("aes")) - newFilter = new Filters::AESFilter(); - else if (filterConfig.starts_with("xor")) - newFilter = new Filters::XorFilter(); // these filters were not deleted. just a note. - else - throw std::invalid_argument("Unknown filter in filterConfig item: " + filterConfig); - - newFilter->loadConfig(filterConfig); - chainedFilters.push_back(newFilter); - } - + for (auto &&filterConfig : filterConfigs) + chainedFilters.push_back(CreateFilterFromConfig(filterConfig)); ptrFilter = new Filters::ChainedFilters(chainedFilters); } diff --git a/src/main.cc b/src/main.cc index 88680ea78db15d0ffc55b61bca64b8bb80b0bde3..8c3c39d293d7aabb467b52a7bfb2b3e87e5c6519 100644 --- a/src/main.cc +++ b/src/main.cc @@ -26,7 +26,7 @@ int real_main(int argc, char **argv) { rlog.info(" '$method@$params', available methods: "); rlog.info(" 'plain@$addr@$port', 'misc@$addr@$portRange@$psk'"); rlog.info("There could be multiple --filter, but they MUST be in correct order. "); - rlog.info("available filters: 'aes@$password' , 'xor@$password'"); + rlog.info("available filters: 'aes@$password' , 'xor@$password', 'reverse@$otherFilter'"); return 0; } auto inboundConfig = args.getValueArg("-i");