From: Pieter Lexis Date: Wed, 22 Oct 2025 12:56:42 +0000 (+0200) Subject: tests(dnsdist): Add initial RCodeAction benchmark X-Git-Tag: rec-5.4.0-beta1~51^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5f7281ae45641f57c8ab3bfc937caa6ef39020dc;p=thirdparty%2Fpdns.git tests(dnsdist): Add initial RCodeAction benchmark --- diff --git a/pdns/dnsdistdist/bench-dnsdist-action-rcode.cc b/pdns/dnsdistdist/bench-dnsdist-action-rcode.cc new file mode 100644 index 0000000000..239e27b0bd --- /dev/null +++ b/pdns/dnsdistdist/bench-dnsdist-action-rcode.cc @@ -0,0 +1,52 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "dnsname.hh" +#define CATCH_CONFIG_NO_MAIN +#include +#include + +#include "dnsdist.hh" +#include "dnsdist-idstate.hh" +#include "dnsdist-dnsparser.hh" +#include "dnsdist-actions-factory.hh" + +TEST_CASE("Actions/RCodeAction", "[actions]") { + InternalQueryState ids; + PacketBuffer data; + GenericDNSPacketWriter pwQ(data, DNSName("dnsdist.test.powerdns.com"), QType::A, QClass::IN, 0); + pwQ.getHeader()->rd = 1; + + dnsdist::ResponseConfig rconfig; + auto action = dnsdist::actions::getRCodeAction(RCode::NXDomain, rconfig); + + DNSQuestion dq(ids, data); // NOLINT + std::string ruleresult; + BENCHMARK("set-nxd") { + return (*action)(&dq, &ruleresult); + }; + + rconfig.setAA = true; + action = dnsdist::actions::getRCodeAction(RCode::NXDomain, rconfig); + BENCHMARK("set-nxd-and-AA") { + return (*action)(&dq, &ruleresult); + }; +} diff --git a/pdns/dnsdistdist/benchmarkrunner.cc b/pdns/dnsdistdist/benchmarkrunner.cc index 6d1bc34a20..9add9fc7ff 100644 --- a/pdns/dnsdistdist/benchmarkrunner.cc +++ b/pdns/dnsdistdist/benchmarkrunner.cc @@ -20,4 +20,175 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define CATCH_CONFIG_MAIN +#include #include +#include "dnsdist.hh" +#include "dnsdist-lua.hh" +#include "dnsdist-rings.hh" +#include "dnsdist-xsk.hh" +#include "dnsdist-tcp.hh" + +// NOTE: This file contains waaaaaay too many mocked things to make bench-dnsdist-action-rcode.cc +// link. In the future, all these functions and declarations should go away and be put into their +// own hh/cc files. + +RecursiveLockGuarded g_lua{LuaContext()}; +shared_ptr g_defaultBPFFilter{nullptr}; +Rings g_rings; +string g_outputBuffer; + +void handleResponseSent([[maybe_unused]] const InternalQueryState& ids, [[maybe_unused]]double udiff, [[maybe_unused]]const ComboAddress& client, [[maybe_unused]]const ComboAddress& backend, [[maybe_unused]]unsigned int size, [[maybe_unused]]const dnsheader& cleartextDH, [[maybe_unused]]dnsdist::Protocol protocol, [[maybe_unused]]bool fromBackend) +{ +} + +void handleResponseSent([[maybe_unused]] const DNSName& qname, [[maybe_unused]]const QType& qtype, [[maybe_unused]]double udiff, [[maybe_unused]]const ComboAddress& client, [[maybe_unused]]const ComboAddress& backend, [[maybe_unused]]unsigned int size, [[maybe_unused]]const dnsheader& cleartextDH, [[maybe_unused]]dnsdist::Protocol outgoingProtocol, [[maybe_unused]]dnsdist::Protocol incomingProtocol, [[maybe_unused]]bool fromBackend) +{ +} + +bool processResponse([[maybe_unused]] PacketBuffer& response, [[maybe_unused]] DNSResponse& dnsResponse, [[maybe_unused]] bool muted) +{ + return false; +} + +void doExitNicely(int exitCode); +void doExitNicely([[maybe_unused]] int exitCode){ +}; + +ProcessQueryResult processQuery([[maybe_unused]] DNSQuestion& dnsQuestion, [[maybe_unused]]std::shared_ptr& selectedBackend) +{ + return ProcessQueryResult::Drop; +}; + +bool processRulesResult([[maybe_unused]] const DNSAction::Action& action, [[maybe_unused]]DNSQuestion& dnsQuestion, [[maybe_unused]]std::string& ruleresult, [[maybe_unused]]bool& drop) +{ + return false; +} + +ProcessQueryResult processQueryAfterRules([[maybe_unused]] DNSQuestion& dnsQuestion, [[maybe_unused]]std::shared_ptr& outgoingBackend) +{ + return ProcessQueryResult::Drop; +} + +bool processResponseAfterRules([[maybe_unused]] PacketBuffer& response, [[maybe_unused]]DNSResponse& dnsResponse, [[maybe_unused]]bool muted) +{ + return false; +} + +bool applyRulesToResponse([[maybe_unused]] const std::vector& respRuleActions, [[maybe_unused]]DNSResponse& dnsResponse) +{ + (void)respRuleActions; + (void)dnsResponse; + return true; +} + +bool handleTimeoutResponseRules([[maybe_unused]] const std::vector& rules, [[maybe_unused]]InternalQueryState& ids, [[maybe_unused]]const std::shared_ptr& d_ds, [[maybe_unused]]const std::shared_ptr& sender) +{ + return false; +} + +void handleServerStateChange([[maybe_unused]] const string& nameWithAddr, [[maybe_unused]]bool newResult) +{ +} + +bool sendUDPResponse([[maybe_unused]] int origFD, [[maybe_unused]]const PacketBuffer& response, [[maybe_unused]]const int delayMsec, [[maybe_unused]]const ComboAddress& origDest, [[maybe_unused]]const ComboAddress& origRemote) +{ + return false; +} + +bool assignOutgoingUDPQueryToBackend([[maybe_unused]] std::shared_ptr& downstream, [[maybe_unused]]uint16_t queryID, [[maybe_unused]]DNSQuestion& dnsQuestion, [[maybe_unused]]PacketBuffer& query, [[maybe_unused]]bool actuallySend) +{ + return true; +} + +#ifdef HAVE_XSK +namespace dnsdist::xsk +{ +bool XskProcessQuery([[maybe_unused]] ClientState& clientState, [[maybe_unused]] XskPacket& packet) +{ + return false; +} +} +#endif /* HAVE_XSK */ + +bool processResponderPacket([[maybe_unused]] std::shared_ptr& dss, [[maybe_unused]] PacketBuffer& response, [[maybe_unused]] InternalQueryState&& ids) +{ + return false; +} + +// NOLINTNEXTLINE(performance-unnecessary-value-param): this is a stub, the real one is not that simple and the performance does not matter +void responderThread([[maybe_unused]] std::shared_ptr dss) +{ +} + +bool checkQueryHeaders([[maybe_unused]] const struct dnsheader& dnsHeader, [[maybe_unused]] ClientState& clientState) { + return true; +} + +bool checkDNSCryptQuery([[maybe_unused]] const ClientState& clientState, [[maybe_unused]] PacketBuffer& query, [[maybe_unused]] std::unique_ptr& dnsCryptQuery, [[maybe_unused]] time_t now, [[maybe_unused]] bool tcp) { + return false; +} + +bool responseContentMatches([[maybe_unused]] const PacketBuffer& response, [[maybe_unused]]const DNSName& qname, [[maybe_unused]]const uint16_t qtype, [[maybe_unused]]const uint16_t qclass, [[maybe_unused]]const std::shared_ptr& remote, [[maybe_unused]]bool allowEmptyResponse) { + return false; +} + + +class UDPTCPCrossQuerySender : public TCPQuerySender +{ +public: + UDPTCPCrossQuerySender() = default; + UDPTCPCrossQuerySender(const UDPTCPCrossQuerySender&) = delete; + UDPTCPCrossQuerySender& operator=(const UDPTCPCrossQuerySender&) = delete; + UDPTCPCrossQuerySender(UDPTCPCrossQuerySender&&) = default; + UDPTCPCrossQuerySender& operator=(UDPTCPCrossQuerySender&&) = default; + ~UDPTCPCrossQuerySender() override = default; + + [[nodiscard]] bool active() const override + { + return true; + } + + void handleResponse([[maybe_unused]] const struct timeval& now, [[maybe_unused]] TCPResponse&& response) override + { + } + + void handleXFRResponse([[maybe_unused]] const struct timeval& now, [[maybe_unused]] TCPResponse&& response) override + { + } + + void notifyIOError([[maybe_unused]] const struct timeval& now, [[maybe_unused]] TCPResponse&& response) override + { + } +}; + + +class UDPCrossProtocolQuery : public CrossProtocolQuery +{ +public: + UDPCrossProtocolQuery() = default; + UDPCrossProtocolQuery(PacketBuffer&& buffer_, InternalQueryState&& ids_, std::shared_ptr backend) : + CrossProtocolQuery(InternalQuery(std::move(buffer_), std::move(ids_)), backend) + { + } + UDPCrossProtocolQuery(const UDPCrossProtocolQuery&) = delete; + UDPCrossProtocolQuery& operator=(const UDPCrossProtocolQuery&) = delete; + UDPCrossProtocolQuery(UDPCrossProtocolQuery&&) = delete; + UDPCrossProtocolQuery& operator=(UDPCrossProtocolQuery&&) = delete; + ~UDPCrossProtocolQuery() override = default; + + std::shared_ptr getTCPQuerySender() override + { + return s_sender; + } + +private: + static std::shared_ptr s_sender; +}; + +std::shared_ptr UDPCrossProtocolQuery::s_sender = std::make_shared(); + +std::unique_ptr getUDPCrossProtocolQueryFromDQ(DNSQuestion& dnsQuestion); +std::unique_ptr getUDPCrossProtocolQueryFromDQ([[maybe_unused]] DNSQuestion& dnsQuestion) +{ + return std::make_unique(); +} diff --git a/pdns/dnsdistdist/meson.build b/pdns/dnsdistdist/meson.build index 300c7a62a1..8d00f3f954 100644 --- a/pdns/dnsdistdist/meson.build +++ b/pdns/dnsdistdist/meson.build @@ -594,8 +594,8 @@ if get_option('unit-tests') } endif -benchmark_sources = [] -benchmark_sources += files( +benchmark_sources = files( + src_dir / 'bench-dnsdist-action-rcode.cc', src_dir / 'bench-dnsdist-dnsparser_cc.cc', src_dir / 'bench-dnsdist-opentelemetry_cc.cc', ) @@ -608,9 +608,18 @@ if get_option('benchmark') ], 'files-extra': [ benchmark_sources, + config_h, + mplexer_sources, + src_dir / 'dnsdist-lbpolicies.cc', + src_dir / 'dnsdist-lua-ffi.cc', + src_dir / 'dnstap.cc', + src_dir / 'fstrm_logger.cc', ], 'deps-extra': [ dep_catch2, + dep_dnstap, + dep_ffi_interface, + dep_lua, dep_protozero, ], }