diff options
Diffstat (limited to '')
-rw-r--r-- | dnsdist-rules.hh | 72 |
1 files changed, 68 insertions, 4 deletions
diff --git a/dnsdist-rules.hh b/dnsdist-rules.hh index 2457b2b..d0f2fcb 100644 --- a/dnsdist-rules.hh +++ b/dnsdist-rules.hh @@ -33,6 +33,7 @@ #include "dnsdist-lua-ffi.hh" #include "dolog.hh" #include "dnsparser.hh" +#include "dns_random.hh" class MaxQPSIPRule : public DNSRule { @@ -556,7 +557,7 @@ private: class HTTPPathRule : public DNSRule { public: - HTTPPathRule(const std::string& path); + HTTPPathRule(std::string path); bool matches(const DNSQuestion* dq) const override; string toString() const override; private: @@ -1055,7 +1056,7 @@ public: { if(d_proba == 1.0) return true; - double rnd = 1.0*random() / RAND_MAX; + double rnd = 1.0*dns_random_uint32() / UINT32_MAX; return rnd > (1.0 - d_proba); } string toString() const override @@ -1069,7 +1070,7 @@ private: class TagRule : public DNSRule { public: - TagRule(const std::string& tag, boost::optional<std::string> value) : d_value(value), d_tag(tag) + TagRule(const std::string& tag, boost::optional<std::string> value) : d_value(std::move(value)), d_tag(tag) { } bool matches(const DNSQuestion* dq) const override @@ -1318,7 +1319,7 @@ private: class ProxyProtocolValueRule : public DNSRule { public: - ProxyProtocolValueRule(uint8_t type, boost::optional<std::string> value): d_value(value), d_type(type) + ProxyProtocolValueRule(uint8_t type, boost::optional<std::string> value): d_value(std::move(value)), d_type(type) { } @@ -1349,3 +1350,66 @@ private: boost::optional<std::string> d_value; uint8_t d_type; }; + +class PayloadSizeRule : public DNSRule +{ + enum class Comparisons : uint8_t { equal, greater, greaterOrEqual, smaller, smallerOrEqual }; +public: + PayloadSizeRule(const std::string& comparison, uint16_t size): d_size(size) + { + if (comparison == "equal") { + d_comparison = Comparisons::equal; + } + else if (comparison == "greater") { + d_comparison = Comparisons::greater; + } + else if (comparison == "greaterOrEqual") { + d_comparison = Comparisons::greaterOrEqual; + } + else if (comparison == "smaller") { + d_comparison = Comparisons::smaller; + } + else if (comparison == "smallerOrEqual") { + d_comparison = Comparisons::smallerOrEqual; + } + else { + throw std::runtime_error("Unsupported comparison '" + comparison + "'"); + } + } + + bool matches(const DNSQuestion* dq) const override + { + const auto size = dq->getData().size(); + + switch (d_comparison) { + case Comparisons::equal: + return size == d_size; + case Comparisons::greater: + return size > d_size; + case Comparisons::greaterOrEqual: + return size >= d_size; + case Comparisons::smaller: + return size < d_size; + case Comparisons::smallerOrEqual: + return size <= d_size; + default: + return false; + } + } + + string toString() const override + { + static const std::array<const std::string, 5> comparisonStr{ + "equal to" , + "greater than", + "equal to or greater than", + "smaller than", + "equal to or smaller than" + }; + return "payload size is " + comparisonStr.at(static_cast<size_t>(d_comparison)) + " " + std::to_string(d_size); + } + +private: + uint16_t d_size; + Comparisons d_comparison; +}; |