From: Charles-Henri Bruyand Date: Thu, 13 Feb 2025 13:45:59 +0000 (+0100) Subject: dnsdist: protobuf, properly set the packetCacheHit field in logged messages X-Git-Tag: dnsdist-2.0.0-alpha1~12^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f7ec620ab2ca65b2b4e99b358fe9403bc94d0eb7;p=thirdparty%2Fpdns.git dnsdist: protobuf, properly set the packetCacheHit field in logged messages --- diff --git a/pdns/dnsdistdist/dnsdist-idstate.hh b/pdns/dnsdistdist/dnsdist-idstate.hh index 48fdeefc30..6f2a9a8b31 100644 --- a/pdns/dnsdistdist/dnsdist-idstate.hh +++ b/pdns/dnsdistdist/dnsdist-idstate.hh @@ -177,6 +177,7 @@ struct InternalQueryState bool useZeroScope{false}; bool forwardedOverUDP{false}; bool selfGenerated{false}; + bool cacheHit{false}; }; struct IDState diff --git a/pdns/dnsdistdist/dnsdist-protobuf.cc b/pdns/dnsdistdist/dnsdist-protobuf.cc index d3b9200dc7..88824c70fb 100644 --- a/pdns/dnsdistdist/dnsdist-protobuf.cc +++ b/pdns/dnsdistdist/dnsdist-protobuf.cc @@ -180,6 +180,9 @@ void DNSDistProtoBufMessage::serialize(std::string& data) const msg.setEDNSSubnet(*d_ednsSubnet, 128); } + if (d_dr != nullptr) { + msg.setPacketCacheHit(d_dr->ids.cacheHit); + } msg.startResponse(); if (d_queryTime) { // coverity[store_truncates_time_t] diff --git a/pdns/dnsdistdist/dnsdist.cc b/pdns/dnsdistdist/dnsdist.cc index a72f503508..481bb87e81 100644 --- a/pdns/dnsdistdist/dnsdist.cc +++ b/pdns/dnsdistdist/dnsdist.cc @@ -1338,6 +1338,7 @@ static bool prepareOutgoingResponse([[maybe_unused]] const ClientState& clientSt DNSResponse dnsResponse(dnsQuestion.ids, dnsQuestion.getMutableData(), backend); dnsResponse.d_incomingTCPState = dnsQuestion.d_incomingTCPState; dnsResponse.ids.selfGenerated = true; + dnsResponse.ids.cacheHit = cacheHit; const auto& chains = dnsdist::configuration::getCurrentRuntimeConfiguration().d_ruleChains; const auto& cacheHitRespRules = dnsdist::rules::getResponseRuleChain(chains, dnsdist::rules::ResponseRuleChain::CacheHitResponseRules); diff --git a/regression-tests.dnsdist/test_Protobuf.py b/regression-tests.dnsdist/test_Protobuf.py index e77d747b81..8c255d114a 100644 --- a/regression-tests.dnsdist/test_Protobuf.py +++ b/regression-tests.dnsdist/test_Protobuf.py @@ -548,6 +548,65 @@ class TestProtobufExtendedDNSErrorTags(DNSDistProtobufTest): self.assertIn(15, msg.meta[0].value.intVal) self.assertIn('Blocked by RPZ!', msg.meta[0].value.stringVal) +class TestProtobufCacheHit(DNSDistProtobufTest): + _config_params = ['_testServerPort', '_protobufServerPort'] + _config_template = """ + newServer{address="127.0.0.1:%s"} + rl = newRemoteLogger('127.0.0.1:%d') + pc = newPacketCache(100, {maxTTL=86400, minTTL=1}) + getPool(""):setCache(pc) + + addResponseAction(AllRule(), RemoteLogResponseAction(rl, nil, false, {serverID='dnsdist-server-1'})) + addCacheHitResponseAction(AllRule(), RemoteLogResponseAction(rl, nil, false, {serverID='dnsdist-server-1'})) + """ + + def testProtobufExtendedError(self): + """ + Protobuf: CacheHit field + """ + name = 'cachehit.protobuf.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 3600, + dns.rdataclass.IN, + dns.rdatatype.A, + '127.0.0.1') + response.answer.append(rrset) + + # fill the cache + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + self.assertTrue(receivedQuery) + self.assertTrue(receivedResponse) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + + if self._protobufQueue.empty(): + # let the protobuf messages the time to get there + time.sleep(1) + + # check the protobuf message corresponding to the UDP response + msg = self.getFirstProtobufMessage() + self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.UDP, response) + self.assertTrue(msg.HasField('packetCacheHit')) + self.assertFalse(msg.packetCacheHit) + + # now shoud be a cache hit + (_, receivedResponse) = self.sendUDPQuery(query, response) + self.assertTrue(receivedResponse) + self.assertEqual(response, receivedResponse) + + if self._protobufQueue.empty(): + # let the protobuf messages the time to get there + time.sleep(1) + + # check the protobuf message corresponding to the UDP response + msg = self.getFirstProtobufMessage() + self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.UDP, response) + self.assertTrue(msg.HasField('packetCacheHit')) + self.assertTrue(msg.packetCacheHit) + class TestProtobufMetaDOH(DNSDistProtobufTest): _serverKey = 'server.key'