From: Charles-Henri Bruyand Date: Mon, 11 Oct 2021 08:12:15 +0000 (+0200) Subject: dnsdist: add incoming and outgoing protocols to grepq X-Git-Tag: dnsdist-1.7.0-alpha2~25^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8110a0aa568fa16b2c7046a0f5bb38d5828eddb2;p=thirdparty%2Fpdns.git dnsdist: add incoming and outgoing protocols to grepq --- diff --git a/pdns/dnsdist-lua-bindings-dnsquestion.cc b/pdns/dnsdist-lua-bindings-dnsquestion.cc index c7ecf3a04d..0ca9b7ce83 100644 --- a/pdns/dnsdist-lua-bindings-dnsquestion.cc +++ b/pdns/dnsdist-lua-bindings-dnsquestion.cc @@ -74,7 +74,7 @@ void setupLuaBindingsDNSQuestion(LuaContext& luaCtx) }); luaCtx.registerFunction("getProtocol", [](const DNSQuestion& dq) { - return dnsdist::ProtocolToString(dq.getProtocol()); + return dq.getProtocol().toPrettyString(); }); luaCtx.registerFunction("sendTrap", [](const DNSQuestion& dq, boost::optional reason) { @@ -238,7 +238,7 @@ void setupLuaBindingsDNSQuestion(LuaContext& luaCtx) }); luaCtx.registerFunction("getProtocol", [](const DNSResponse& dr) { - return dnsdist::ProtocolToString(dr.getProtocol()); + return dr.getProtocol().toString(); }); luaCtx.registerFunction("sendTrap", [](const DNSResponse& dr, boost::optional reason) { diff --git a/pdns/dnsdist-lua-inspection.cc b/pdns/dnsdist-lua-inspection.cc index 44aafbe555..71ff7da879 100644 --- a/pdns/dnsdist-lua-inspection.cc +++ b/pdns/dnsdist-lua-inspection.cc @@ -455,8 +455,8 @@ void setupLuaInspection(LuaContext& luaCtx) std::multimap out; - boost::format fmt("%-7.1f %-47s %-12s %-5d %-25s %-5s %-6.1f %-2s %-2s %-2s %-s\n"); - g_outputBuffer+= (fmt % "Time" % "Client" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str(); + boost::format fmt("%-7.1f %-47s %-12s %-12s %-5d %-25s %-5s %-6.1f %-2s %-2s %-2s %-s\n"); + g_outputBuffer+= (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str(); if(msec==-1) { for(const auto& c : qr) { @@ -478,7 +478,7 @@ void setupLuaInspection(LuaContext& luaCtx) if (c.dh.opcode != 0) { extra = " (" + Opcode::to_s(c.dh.opcode) + ")"; } - out.insert(make_pair(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % "" % htons(c.dh.id) % c.name.toString() % qt.toString() % "" % (c.dh.tc ? "TC" : "") % (c.dh.rd? "RD" : "") % (c.dh.aa? "AA" : "") % ("Question" + extra)).str() )) ; + out.insert(make_pair(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % dnsdist::Protocol(c.protocol).toString() % "" % htons(c.dh.id) % c.name.toString() % qt.toString() % "" % (c.dh.tc ? "TC" : "") % (c.dh.rd? "RD" : "") % (c.dh.aa? "AA" : "") % ("Question" + extra)).str() )) ; if(limit && *limit==++num) break; @@ -516,10 +516,10 @@ void setupLuaInspection(LuaContext& luaCtx) } if (c.usec != std::numeric_limits::max()) { - out.insert(make_pair(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % c.ds.toStringWithPort() % htons(c.dh.id) % c.name.toString() % qt.toString() % (c.usec/1000.0) % (c.dh.tc ? "TC" : "") % (c.dh.rd? "RD" : "") % (c.dh.aa? "AA" : "") % (RCode::to_s(c.dh.rcode) + extra)).str() )) ; + out.insert(make_pair(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % dnsdist::Protocol(c.protocol).toString() % c.ds.toStringWithPort() % htons(c.dh.id) % c.name.toString() % qt.toString() % (c.usec/1000.0) % (c.dh.tc ? "TC" : "") % (c.dh.rd? "RD" : "") % (c.dh.aa? "AA" : "") % (RCode::to_s(c.dh.rcode) + extra)).str() )) ; } else { - out.insert(make_pair(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % c.ds.toStringWithPort() % htons(c.dh.id) % c.name.toString() % qt.toString() % "T.O" % (c.dh.tc ? "TC" : "") % (c.dh.rd? "RD" : "") % (c.dh.aa? "AA" : "") % (RCode::to_s(c.dh.rcode) + extra)).str() )) ; + out.insert(make_pair(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % dnsdist::Protocol(c.protocol).toString() % c.ds.toStringWithPort() % htons(c.dh.id) % c.name.toString() % qt.toString() % "T.O" % (c.dh.tc ? "TC" : "") % (c.dh.rd? "RD" : "") % (c.dh.aa? "AA" : "") % (RCode::to_s(c.dh.rcode) + extra)).str() )) ; } if (limit && *limit == ++num) { diff --git a/pdns/dnsdist-protocols.hh b/pdns/dnsdist-protocols.hh index 0b3b540a0a..2aef0a8f94 100644 --- a/pdns/dnsdist-protocols.hh +++ b/pdns/dnsdist-protocols.hh @@ -26,15 +26,28 @@ namespace dnsdist { -enum class Protocol : uint8_t +class Protocol { - DoUDP, - DoTCP, - DNSCryptUDP, - DNSCryptTCP, - DoT, - DoH -}; +public: + Protocol(uint8_t protocol = 0); + Protocol& operator=(const char*); + Protocol& operator=(const std::string&); + operator uint8_t() const; + const std::string& toString() const; + const std::string& toPrettyString() const; + + enum typeenum : uint8_t + { + DoUDP, + DoTCP, + DNSCryptUDP, + DNSCryptTCP, + DoT, + DoH + }; -const std::string& ProtocolToString(Protocol proto); +private: + static uint8_t fromString(const std::string& s); + uint8_t d_protocol; +}; } diff --git a/pdns/dnsdist-rings.cc b/pdns/dnsdist-rings.cc index ce24a5f646..81221d1f8f 100644 --- a/pdns/dnsdist-rings.cc +++ b/pdns/dnsdist-rings.cc @@ -108,9 +108,9 @@ size_t Rings::loadFromFile(const std::string& filepath, const struct timespec& n vector parts; stringtok(parts, line, " \t,"); - if (parts.size() == 7) { + if (parts.size() == 8) { } - else if (parts.size() >= 10 && parts.size() <= 12) { + else if (parts.size() >= 11 && parts.size() <= 13) { isResponse = true; } else { @@ -138,7 +138,9 @@ size_t Rings::loadFromFile(const std::string& filepath, const struct timespec& n ComboAddress from(parts.at(idx++)); ComboAddress to; + dnsdist::Protocol protocol; + protocol = parts.at(idx++); if (isResponse) { to = ComboAddress(parts.at(idx++)); } @@ -148,10 +150,10 @@ size_t Rings::loadFromFile(const std::string& filepath, const struct timespec& n QType qtype(QType::chartocode(parts.at(idx++).c_str())); if (isResponse) { - insertResponse(when, from, qname, qtype.getCode(), 0, 0, dh, to); + insertResponse(when, from, qname, qtype.getCode(), 0, 0, dh, to, protocol); } else { - insertQuery(when, from, qname, qtype.getCode(), 0, dh); + insertQuery(when, from, qname, qtype.getCode(), 0, dh, protocol); } ++inserted; } diff --git a/pdns/dnsdist-rings.hh b/pdns/dnsdist-rings.hh index e8c118ba5c..87c8c94211 100644 --- a/pdns/dnsdist-rings.hh +++ b/pdns/dnsdist-rings.hh @@ -31,7 +31,7 @@ #include "iputils.hh" #include "lock.hh" #include "stat_t.hh" - +#include "dnsdist-protocols.hh" struct Rings { struct Query @@ -42,6 +42,8 @@ struct Rings { struct dnsheader dh; uint16_t size; uint16_t qtype; + // incoming protocol + uint8_t protocol; }; struct Response { @@ -53,6 +55,8 @@ struct Rings { unsigned int usec; unsigned int size; uint16_t qtype; + // outgoing protocol + uint8_t protocol; }; struct Shard @@ -114,13 +118,13 @@ struct Rings { return d_nbResponseEntries; } - void insertQuery(const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, uint16_t size, const struct dnsheader& dh) + void insertQuery(const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, uint16_t size, const struct dnsheader& dh, uint8_t protocol) { for (size_t idx = 0; idx < d_nbLockTries; idx++) { auto& shard = getOneShard(); auto lock = shard->queryRing.try_lock(); if (lock.owns_lock()) { - insertQueryLocked(*lock, when, requestor, name, qtype, size, dh); + insertQueryLocked(*lock, when, requestor, name, qtype, size, dh, protocol); return; } if (d_keepLockingStats) { @@ -134,16 +138,16 @@ struct Rings { } auto& shard = getOneShard(); auto lock = shard->queryRing.lock(); - insertQueryLocked(*lock, when, requestor, name, qtype, size, dh); + insertQueryLocked(*lock, when, requestor, name, qtype, size, dh, protocol); } - void insertResponse(const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, unsigned int usec, unsigned int size, const struct dnsheader& dh, const ComboAddress& backend) + void insertResponse(const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, unsigned int usec, unsigned int size, const struct dnsheader& dh, const ComboAddress& backend, uint8_t protocol) { for (size_t idx = 0; idx < d_nbLockTries; idx++) { auto& shard = getOneShard(); auto lock = shard->respRing.try_lock(); if (lock.owns_lock()) { - insertResponseLocked(*lock, when, requestor, name, qtype, usec, size, dh, backend); + insertResponseLocked(*lock, when, requestor, name, qtype, usec, size, dh, backend, protocol); return; } if (d_keepLockingStats) { @@ -157,7 +161,7 @@ struct Rings { } auto& shard = getOneShard(); auto lock = shard->respRing.lock(); - insertResponseLocked(*lock, when, requestor, name, qtype, usec, size, dh, backend); + insertResponseLocked(*lock, when, requestor, name, qtype, usec, size, dh, backend, protocol); } void clear() @@ -197,20 +201,20 @@ private: return d_shards[getShardId()]; } - void insertQueryLocked(boost::circular_buffer& ring, const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, uint16_t size, const struct dnsheader& dh) + void insertQueryLocked(boost::circular_buffer& ring, const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, uint16_t size, const struct dnsheader& dh, uint8_t protocol) { if (!ring.full()) { d_nbQueryEntries++; } - ring.push_back({requestor, name, when, dh, size, qtype}); + ring.push_back({requestor, name, when, dh, size, qtype, protocol}); } - void insertResponseLocked(boost::circular_buffer& ring, const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, unsigned int usec, unsigned int size, const struct dnsheader& dh, const ComboAddress& backend) + void insertResponseLocked(boost::circular_buffer& ring, const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, unsigned int usec, unsigned int size, const struct dnsheader& dh, const ComboAddress& backend, uint8_t protocol) { if (!ring.full()) { d_nbResponseEntries++; } - ring.push_back({requestor, backend, name, when, dh, usec, size, qtype}); + ring.push_back({requestor, backend, name, when, dh, usec, size, qtype, protocol}); } std::atomic d_nbQueryEntries; diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index cf69ed1d89..23ccce62d6 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -254,7 +254,7 @@ static void handleResponseSent(std::shared_ptr& stat double udiff = ids.sentTime.udiff(); vinfolog("Got answer from %s, relayed to %s (%s, %d bytes), took %f usec", ds->remote.toStringWithPort(), ids.origRemote.toStringWithPort(), (state->d_handler.isTLS() ? "DoT" : "TCP"), currentResponse.d_buffer.size(), udiff); - ::handleResponseSent(ids, udiff, state->d_ci.remote, ds->remote, static_cast(currentResponse.d_buffer.size()), currentResponse.d_cleartextDH); + ::handleResponseSent(ids, udiff, state->d_ci.remote, ds->remote, static_cast(currentResponse.d_buffer.size()), currentResponse.d_cleartextDH, ds->getProtocol()); updateTCPLatency(ds, udiff); } diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index a8501cc27d..50d9f620c4 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -551,11 +551,11 @@ static void pickBackendSocketsReadyForReceiving(const std::shared_ptrmplexer.lock())->getAvailableFDs(ready, 1000); } -void handleResponseSent(const IDState& ids, double udiff, const ComboAddress& client, const ComboAddress& backend, unsigned int size, const dnsheader& cleartextDH) +void handleResponseSent(const IDState& ids, double udiff, const ComboAddress& client, const ComboAddress& backend, unsigned int size, const dnsheader& cleartextDH, uint8_t protocol) { struct timespec ts; gettime(&ts); - g_rings.insertResponse(ts, client, ids.qname, ids.qtype, static_cast(udiff), size, cleartextDH, backend); + g_rings.insertResponse(ts, client, ids.qname, ids.qtype, static_cast(udiff), size, cleartextDH, backend, protocol); switch (cleartextDH.rcode) { case RCode::NXDomain: @@ -696,7 +696,7 @@ void responderThread(std::shared_ptr dss) double udiff = ids->sentTime.udiff(); vinfolog("Got answer from %s, relayed to %s, took %f usec", dss->remote.toStringWithPort(), ids->origRemote.toStringWithPort(), udiff); - handleResponseSent(*ids, udiff, *dr.remote, dss->remote, static_cast(got), cleartextDH); + handleResponseSent(*ids, udiff, *dr.remote, dss->remote, static_cast(got), cleartextDH, dss->getProtocol()); dss->latencyUsec = (127.0 * dss->latencyUsec / 128.0) + udiff/128.0; @@ -842,7 +842,7 @@ bool processRulesResult(const DNSAction::Action& action, DNSQuestion& dq, std::s static bool applyRulesToQuery(LocalHolders& holders, DNSQuestion& dq, const struct timespec& now) { - g_rings.insertQuery(now, *dq.remote, *dq.qname, dq.qtype, dq.getData().size(), *dq.getHeader()); + g_rings.insertQuery(now, *dq.remote, *dq.qname, dq.qtype, dq.getData().size(), *dq.getHeader(), dq.getProtocol()); if (g_qcount.enabled) { string qname = (*dq.qname).toLogString(); @@ -1354,7 +1354,7 @@ public: double udiff = ids.sentTime.udiff(); vinfolog("Got answer from %s, relayed to %s (UDP), took %f usec", d_ds->remote.toStringWithPort(), ids.origRemote.toStringWithPort(), udiff); - handleResponseSent(ids, udiff, *dr.remote, d_ds->remote, response.d_buffer.size(), cleartextDH); + handleResponseSent(ids, udiff, *dr.remote, d_ds->remote, response.d_buffer.size(), cleartextDH, d_ds->getProtocol()); d_ds->latencyUsec = (127.0 * d_ds->latencyUsec / 128.0) + udiff/128.0; @@ -1899,7 +1899,7 @@ static void healthChecksThread() memset(&fake, 0, sizeof(fake)); fake.id = ids.origID; - g_rings.insertResponse(ts, ids.origRemote, ids.qname, ids.qtype, std::numeric_limits::max(), 0, fake, dss->remote); + g_rings.insertResponse(ts, ids.origRemote, ids.qname, ids.qtype, std::numeric_limits::max(), 0, fake, dss->remote, dss->getProtocol()); } } } diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 2f4d6480fc..e046707b14 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -865,7 +865,19 @@ struct DownstreamState } bool passCrossProtocolQuery(std::unique_ptr&& cpq); - + dnsdist::Protocol getProtocol() const + { + if (isDoH()) { + return dnsdist::Protocol::DoH; + } + if (d_tlsCtx != nullptr) { + return dnsdist::Protocol::DoT; + } + if (isTCPOnly()) { + return dnsdist::Protocol::DoTCP; + } + return dnsdist::Protocol::DoUDP; + } private: std::string name; std::string nameWithAddr; @@ -1060,6 +1072,6 @@ void setIDStateFromDNSQuestion(IDState& ids, DNSQuestion& dq, DNSName&& qname); int pickBackendSocketForSending(std::shared_ptr& state); ssize_t udpClientSendRequestToBackend(const std::shared_ptr& ss, const int sd, const PacketBuffer& request, bool healthCheck = false); -void handleResponseSent(const IDState& ids, double udiff, const ComboAddress& client, const ComboAddress& backend, unsigned int size, const dnsheader& cleartextDH); +void handleResponseSent(const IDState& ids, double udiff, const ComboAddress& client, const ComboAddress& backend, unsigned int size, const dnsheader& cleartextDH, uint8_t protocol); void carbonDumpThread(); diff --git a/pdns/dnsdistdist/dnsdist-protocols.cc b/pdns/dnsdistdist/dnsdist-protocols.cc index 5c351c153a..e9c66ed4f2 100644 --- a/pdns/dnsdistdist/dnsdist-protocols.cc +++ b/pdns/dnsdistdist/dnsdist-protocols.cc @@ -19,13 +19,65 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + +#include + #include "dnsdist-protocols.hh" namespace dnsdist { -const std::string& ProtocolToString(Protocol proto) +static const std::vector names = { + "DoUDP", + "DoTCP", + "DNSCryptUDP", + "DNSCryptTCP", + "DoT", + "DoH"}; + +static const std::vector prettyNames = { + "Do53 UDP", + "Do53 TCP", + "DNSCrypt UDP", + "DNSCrypt TCP", + "DNS over TLS", + "DNS over HTTPS"}; + +Protocol::Protocol(uint8_t protocol) : + d_protocol(protocol) +{ +} +Protocol& Protocol::operator=(const char* s) { - static const std::vector values = {"Do53 UDP", "Do53 TCP", "DNSCrypt UDP", "DNSCrypt TCP", "DNS over TLS", "DNS over HTTPS"}; - return values.at(static_cast(proto)); + std::string str(s); + d_protocol = Protocol::fromString(str); + + return *this; +} +Protocol& Protocol::operator=(const std::string& s) +{ + d_protocol = Protocol::fromString(s); + + return *this; +} +Protocol::operator uint8_t() const +{ + return d_protocol; +} +const std::string& Protocol::toString() const +{ + return names.at(static_cast(d_protocol)); +} +const std::string& Protocol::toPrettyString() const +{ + return prettyNames.at(static_cast(d_protocol)); +} +uint8_t Protocol::fromString(const std::string& s) +{ + const auto& it = std::find(names.begin(), names.end(), s); + if (it != names.end()) { + return std::distance(names.begin(), it); + } + + return 0; } } diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 5737b7fb6e..f87dba226a 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -465,7 +465,7 @@ public: double udiff = du->ids.sentTime.udiff(); vinfolog("Got answer from %s, relayed to %s (https), took %f usec", du->downstream->remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff); - handleResponseSent(du->ids, udiff, *dr.remote, du->downstream->remote, du->response.size(), cleartextDH); + handleResponseSent(du->ids, udiff, *dr.remote, du->downstream->remote, du->response.size(), cleartextDH, du->downstream->getProtocol()); ++g_stats.responses; if (du->ids.cs) { @@ -1655,7 +1655,7 @@ void DOHUnit::handleUDPResponse(PacketBuffer&& udpResponse, IDState&& state) double udiff = ids.sentTime.udiff(); vinfolog("Got answer from %s, relayed to %s (https), took %f usec", downstream->remote.toStringWithPort(), ids.origRemote.toStringWithPort(), udiff); - handleResponseSent(ids, udiff, *dr.remote, downstream->remote, response.size(), cleartextDH); + handleResponseSent(ids, udiff, *dr.remote, downstream->remote, response.size(), cleartextDH, downstream->getProtocol()); ++g_stats.responses; if (ids.cs) { diff --git a/pdns/dnsdistdist/test-dnsdistdynblocks_hh.cc b/pdns/dnsdistdist/test-dnsdistdynblocks_hh.cc index 374f8db2a7..91bd26c39a 100644 --- a/pdns/dnsdistdist/test-dnsdistdynblocks_hh.cc +++ b/pdns/dnsdistdist/test-dnsdistdynblocks_hh.cc @@ -24,6 +24,8 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate) { ComboAddress backend("192.0.2.42"); uint16_t qtype = QType::AAAA; uint16_t size = 42; + uint8_t protocol = dnsdist::Protocol::DoUDP; + uint8_t outgoingProtocol = dnsdist::Protocol::DoUDP; unsigned int responseTime = 0; struct timespec now; gettime(&now); @@ -49,10 +51,10 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate) { g_dynblockNMG.setState(emptyNMG); for (size_t idx = 0; idx < numberOfQueries; idx++) { - g_rings.insertQuery(now, requestor1, qname, qtype, size, dh); + g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol); /* we do not care about the response during that test, but we want to make sure these do not interfere with the computation */ - g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend); + g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), numberOfQueries); BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries); @@ -71,8 +73,8 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate) { g_dynblockNMG.setState(emptyNMG); for (size_t idx = 0; idx < numberOfQueries; idx++) { - g_rings.insertQuery(now, requestor1, qname, qtype, size, dh); - g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend); + g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol); + g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries); @@ -103,8 +105,8 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate) { for (size_t idx = 0; idx < numberOfQueries; idx++) { struct timespec when = now; when.tv_sec -= (9 - timeIdx); - g_rings.insertQuery(when, requestor1, qname, qtype, size, dh); - g_rings.insertResponse(when, requestor1, qname, qtype, responseTime, size, dh, backend); + g_rings.insertQuery(when, requestor1, qname, qtype, size, dh, protocol); + g_rings.insertResponse(when, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol); } } BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries * numberOfSeconds); @@ -160,6 +162,8 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate_responses) { ComboAddress backend("192.0.2.42"); uint16_t qtype = QType::AAAA; uint16_t size = 42; + uint8_t protocol = dnsdist::Protocol::DoUDP; + uint8_t outgoingProtocol = dnsdist::Protocol::DoUDP; unsigned int responseTime = 0; struct timespec now; gettime(&now); @@ -195,10 +199,10 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate_responses) { struct timespec when = now; when.tv_sec -= (99 - timeIdx); for (size_t idx = 0; idx < numberOfQueries; idx++) { - g_rings.insertQuery(when, requestor1, qname, qtype, size, dh); + g_rings.insertQuery(when, requestor1, qname, qtype, size, dh, protocol); /* we do not care about the response during that test, but we want to make sure these do not interfere with the computation */ - g_rings.insertResponse(when, requestor1, qname, qtype, responseTime, size, dh, backend); + g_rings.insertResponse(when, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol); } } BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), numberOfQueries * 100); @@ -217,6 +221,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QTypeRate) { ComboAddress requestor2("192.0.2.2"); uint16_t qtype = QType::AAAA; uint16_t size = 42; + uint8_t protocol = dnsdist::Protocol::DoUDP; struct timespec now; gettime(&now); NetmaskTree emptyNMG; @@ -241,7 +246,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QTypeRate) { g_dynblockNMG.setState(emptyNMG); for (size_t idx = 0; idx < numberOfQueries; idx++) { - g_rings.insertQuery(now, requestor1, qname, qtype, size, dh); + g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries); @@ -259,7 +264,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QTypeRate) { g_dynblockNMG.setState(emptyNMG); for (size_t idx = 0; idx < numberOfQueries; idx++) { - g_rings.insertQuery(now, requestor1, qname, QType::A, size, dh); + g_rings.insertQuery(now, requestor1, qname, QType::A, size, dh, protocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries); @@ -277,7 +282,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QTypeRate) { g_dynblockNMG.setState(emptyNMG); for (size_t idx = 0; idx < numberOfQueries; idx++) { - g_rings.insertQuery(now, requestor1, qname, qtype, size, dh); + g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries); @@ -304,6 +309,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_RCodeRate) { ComboAddress backend("192.0.2.42"); uint16_t qtype = QType::AAAA; uint16_t size = 42; + uint8_t outgoingProtocol = dnsdist::Protocol::DoUDP; unsigned int responseTime = 100 * 1000; /* 100ms */ struct timespec now; gettime(&now); @@ -331,7 +337,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_RCodeRate) { dh.rcode = rcode; for (size_t idx = 0; idx < numberOfResponses; idx++) { - g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend); + g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), numberOfResponses); @@ -349,7 +355,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_RCodeRate) { dh.rcode = RCode::FormErr; for (size_t idx = 0; idx < numberOfResponses; idx++) { - g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend); + g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), numberOfResponses); @@ -368,7 +374,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_RCodeRate) { dh.rcode = rcode; for (size_t idx = 0; idx < numberOfResponses; idx++) { - g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend); + g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), numberOfResponses); @@ -395,6 +401,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_RCodeRatio) { ComboAddress backend("192.0.2.42"); uint16_t qtype = QType::AAAA; uint16_t size = 42; + uint8_t outgoingProtocol = dnsdist::Protocol::DoUDP; unsigned int responseTime = 100 * 1000; /* 100ms */ struct timespec now; gettime(&now); @@ -421,11 +428,11 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_RCodeRatio) { dh.rcode = rcode; for (size_t idx = 0; idx < 20; idx++) { - g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend); + g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol); } dh.rcode = RCode::NoError; for (size_t idx = 0; idx < 80; idx++) { - g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend); + g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), 100U); @@ -442,7 +449,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_RCodeRatio) { dh.rcode = RCode::FormErr; for (size_t idx = 0; idx < 50; idx++) { - g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend); + g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), 50U); @@ -460,11 +467,11 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_RCodeRatio) { dh.rcode = rcode; for (size_t idx = 0; idx < 21; idx++) { - g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend); + g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol); } dh.rcode = RCode::NoError; for (size_t idx = 0; idx < 79; idx++) { - g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend); + g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), 100U); @@ -490,11 +497,11 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_RCodeRatio) { dh.rcode = rcode; for (size_t idx = 0; idx < 11; idx++) { - g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend); + g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol); } dh.rcode = RCode::NoError; for (size_t idx = 0; idx < 39; idx++) { - g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend); + g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), 50U); @@ -512,6 +519,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_ResponseByteRate) { ComboAddress backend("192.0.2.42"); uint16_t qtype = QType::AAAA; uint16_t size = 100; + uint8_t outgoingProtocol = dnsdist::Protocol::DoUDP; unsigned int responseTime = 100 * 1000; /* 100ms */ struct timespec now; gettime(&now); @@ -539,7 +547,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_ResponseByteRate) { dh.rcode = rcode; for (size_t idx = 0; idx < numberOfResponses; idx++) { - g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend); + g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), numberOfResponses); @@ -557,7 +565,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_ResponseByteRate) { dh.rcode = rcode; for (size_t idx = 0; idx < numberOfResponses; idx++) { - g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend); + g_rings.insertResponse(now, requestor1, qname, qtype, responseTime, size, dh, backend, outgoingProtocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfResponseEntries(), numberOfResponses); @@ -583,6 +591,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_Warning) { ComboAddress requestor2("192.0.2.2"); uint16_t qtype = QType::AAAA; uint16_t size = 42; + uint8_t protocol = dnsdist::Protocol::DoUDP; struct timespec now; gettime(&now); NetmaskTree emptyNMG; @@ -607,7 +616,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_Warning) { g_dynblockNMG.setState(emptyNMG); for (size_t idx = 0; idx < numberOfQueries; idx++) { - g_rings.insertQuery(now, requestor1, qname, qtype, size, dh); + g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries); @@ -625,7 +634,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_Warning) { g_dynblockNMG.setState(emptyNMG); for (size_t idx = 0; idx < numberOfQueries; idx++) { - g_rings.insertQuery(now, requestor1, qname, qtype, size, dh); + g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries); @@ -653,7 +662,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_Warning) { BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), 0U); for (size_t idx = 0; idx < numberOfQueries; idx++) { - g_rings.insertQuery(now, requestor1, qname, qtype, size, dh); + g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries); @@ -682,7 +691,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_Warning) { BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), 0U); for (size_t idx = 0; idx < numberOfQueries; idx++) { - g_rings.insertQuery(now, requestor1, qname, qtype, size, dh); + g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries); @@ -713,7 +722,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_Warning) { g_dynblockNMG.setState(emptyNMG); for (size_t idx = 0; idx < numberOfQueries; idx++) { - g_rings.insertQuery(now, requestor1, qname, qtype, size, dh); + g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries); @@ -741,6 +750,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_Ranges) { ComboAddress requestor2("192.0.2.42"); uint16_t qtype = QType::AAAA; uint16_t size = 42; + uint8_t protocol = dnsdist::Protocol::DoUDP; struct timespec now; gettime(&now); NetmaskTree emptyNMG; @@ -769,8 +779,8 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_Ranges) { g_dynblockNMG.setState(emptyNMG); for (size_t idx = 0; idx < numberOfQueries; idx++) { - g_rings.insertQuery(now, requestor1, qname, qtype, size, dh); - g_rings.insertQuery(now, requestor2, qname, qtype, size, dh); + g_rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol); + g_rings.insertQuery(now, requestor2, qname, qtype, size, dh, protocol); } BOOST_CHECK_EQUAL(g_rings.getNumberOfQueryEntries(), numberOfQueries * 2); @@ -795,6 +805,8 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesMetricsCache_GetTopN) { DNSName qname("rings.powerdns.com."); uint16_t qtype = QType::AAAA; uint16_t size = 42; + uint8_t protocol = dnsdist::Protocol::DoUDP; + uint8_t outgoingProtocol = dnsdist::Protocol::DoUDP; struct timespec now; gettime(&now); NetmaskTree emptyNMG; @@ -821,7 +833,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesMetricsCache_GetTopN) { */ for (size_t idx = 0; idx < 256; idx++) { const ComboAddress requestor("192.0.2." + std::to_string(idx)); - g_rings.insertQuery(now, requestor, qname, qtype, size, dh); + g_rings.insertQuery(now, requestor, qname, qtype, size, dh, protocol); } /* we apply the rules, all clients should be blocked */ @@ -877,7 +889,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesMetricsCache_GetTopN) { /* insert one fake response for 255 DNS names */ const ComboAddress requestor("192.0.2.1"); for (size_t idx = 0; idx < 256; idx++) { - g_rings.insertResponse(now, requestor, DNSName(std::to_string(idx)) + qname, qtype, 1000 /*usec*/, size, dh, requestor /* backend, technically, but we don't care */); + g_rings.insertResponse(now, requestor, DNSName(std::to_string(idx)) + qname, qtype, 1000 /*usec*/, size, dh, requestor /* backend, technically, but we don't care */, outgoingProtocol); } /* we apply the rules, all suffixes should be blocked */ @@ -937,7 +949,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesMetricsCache_GetTopN) { for (size_t idxC = 0; !done && idxC < 256; idxC++) { for (size_t idxD = 0; !done && idxD < 256; idxD++) { const DNSName victim(std::to_string(idxB) + "." + std::to_string(idxC) + "." + std::to_string(idxD) + qname.toString()); - g_rings.insertResponse(now, requestor, victim, qtype, 1000 /*usec*/, size, dh, requestor /* backend, technically, but we don't care */); + g_rings.insertResponse(now, requestor, victim, qtype, 1000 /*usec*/, size, dh, requestor /* backend, technically, but we don't care */, outgoingProtocol); if (g_rings.getNumberOfQueryEntries() == 1000000) { done = true; break; @@ -979,7 +991,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesMetricsCache_GetTopN) { for (size_t idxC = 0; !done && idxC < 256; idxC++) { for (size_t idxD = 0; !done && idxD < 256; idxD++) { const ComboAddress requestor("192." + std::to_string(idxB) + "." + std::to_string(idxC) + "." + std::to_string(idxD)); - g_rings.insertQuery(now, requestor, qname, qtype, size, dh); + g_rings.insertQuery(now, requestor, qname, qtype, size, dh, protocol); if (g_rings.getNumberOfQueryEntries() == 1000000) { done = true; break; diff --git a/pdns/dnsdistdist/test-dnsdistrings_cc.cc b/pdns/dnsdistdist/test-dnsdistrings_cc.cc index b0194bc95d..dac459908e 100644 --- a/pdns/dnsdistdist/test-dnsdistrings_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistrings_cc.cc @@ -30,12 +30,14 @@ static void test_ring(size_t maxEntries, size_t numberOfShards, size_t nbLockTri ComboAddress requestor2("192.0.2.2"); uint16_t qtype = QType::AAAA; uint16_t size = 42; + uint8_t protocol = dnsdist::Protocol::DoUDP; + uint8_t outgoingProtocol = dnsdist::Protocol::DoUDP; struct timespec now; gettime(&now); /* fill the query ring */ for (size_t idx = 0; idx < maxEntries; idx++) { - rings.insertQuery(now, requestor1, qname, qtype, size, dh); + rings.insertQuery(now, requestor1, qname, qtype, size, dh, protocol); } BOOST_CHECK_EQUAL(rings.getNumberOfQueryEntries(), maxEntries); BOOST_CHECK_EQUAL(rings.getNumberOfResponseEntries(), 0U); @@ -53,7 +55,7 @@ static void test_ring(size_t maxEntries, size_t numberOfShards, size_t nbLockTri /* push enough queries to get rid of the existing ones */ for (size_t idx = 0; idx < maxEntries; idx++) { - rings.insertQuery(now, requestor2, qname, qtype, size, dh); + rings.insertQuery(now, requestor2, qname, qtype, size, dh, protocol); } BOOST_CHECK_EQUAL(rings.getNumberOfQueryEntries(), maxEntries); BOOST_CHECK_EQUAL(rings.getNumberOfResponseEntries(), 0U); @@ -74,7 +76,7 @@ static void test_ring(size_t maxEntries, size_t numberOfShards, size_t nbLockTri /* fill the response ring */ for (size_t idx = 0; idx < maxEntries; idx++) { - rings.insertResponse(now, requestor1, qname, qtype, latency, size, dh, server); + rings.insertResponse(now, requestor1, qname, qtype, latency, size, dh, server, outgoingProtocol); } BOOST_CHECK_EQUAL(rings.getNumberOfQueryEntries(), maxEntries); BOOST_CHECK_EQUAL(rings.getNumberOfResponseEntries(), maxEntries); @@ -94,7 +96,7 @@ static void test_ring(size_t maxEntries, size_t numberOfShards, size_t nbLockTri /* push enough responses to get rid of the existing ones */ for (size_t idx = 0; idx < maxEntries; idx++) { - rings.insertResponse(now, requestor2, qname, qtype, latency, size, dh, server); + rings.insertResponse(now, requestor2, qname, qtype, latency, size, dh, server, outgoingProtocol); } BOOST_CHECK_EQUAL(rings.getNumberOfQueryEntries(), maxEntries); BOOST_CHECK_EQUAL(rings.getNumberOfResponseEntries(), maxEntries); @@ -171,8 +173,8 @@ static void ringReaderThread(Rings& rings, std::atomic& done, size_t numbe static void ringWriterThread(Rings& rings, size_t numberOfEntries, const Rings::Query& query, const Rings::Response& response) { for (size_t idx = 0; idx < numberOfEntries; idx++) { - rings.insertQuery(query.when, query.requestor, query.name, query.qtype, query.size, query.dh); - rings.insertResponse(response.when, response.requestor, response.name, response.qtype, response.usec, response.size, response.dh, response.ds); + rings.insertQuery(query.when, query.requestor, query.name, query.qtype, query.size, query.dh, query.protocol); + rings.insertResponse(response.when, response.requestor, response.name, response.qtype, response.usec, response.size, response.dh, response.ds, response.protocol); } } @@ -199,10 +201,12 @@ BOOST_AUTO_TEST_CASE(test_Rings_Threaded) { unsigned int latency = 100; uint16_t qtype = QType::AAAA; uint16_t size = 42; + uint8_t protocol = dnsdist::Protocol::DoUDP; + uint8_t outgoingProtocol = dnsdist::Protocol::DoUDP; Rings rings(numberOfEntries, numberOfShards, lockAttempts, true); - Rings::Query query({requestor, qname, now, dh, size, qtype}); - Rings::Response response({requestor, server, qname, now, dh, latency, size, qtype}); + Rings::Query query({requestor, qname, now, dh, size, qtype, protocol}); + Rings::Response response({requestor, server, qname, now, dh, latency, size, qtype, outgoingProtocol}); std::atomic done(false); std::vector writerThreads; diff --git a/pdns/dnsdistdist/test-dnsdisttcp_cc.cc b/pdns/dnsdistdist/test-dnsdisttcp_cc.cc index a02d3ec839..a0e5682d5a 100644 --- a/pdns/dnsdistdist/test-dnsdisttcp_cc.cc +++ b/pdns/dnsdistdist/test-dnsdisttcp_cc.cc @@ -61,7 +61,7 @@ uint64_t getLatencyCount(const std::string&) return 0; } -void handleResponseSent(const IDState& ids, double udiff, const ComboAddress& client, const ComboAddress& backend, unsigned int size, const dnsheader& cleartextDH) +void handleResponseSent(const IDState& ids, double udiff, const ComboAddress& client, const ComboAddress& backend, unsigned int size, const dnsheader& cleartextDH, uint8_t protocol) { }