]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: protobuf, properly set the packetCacheHit field in logged messages
authorCharles-Henri Bruyand <charles-henri.bruyand@open-xchange.com>
Thu, 13 Feb 2025 13:45:59 +0000 (14:45 +0100)
committerCharles-Henri Bruyand <charles-henri.bruyand@open-xchange.com>
Thu, 13 Feb 2025 13:53:24 +0000 (14:53 +0100)
pdns/dnsdistdist/dnsdist-idstate.hh
pdns/dnsdistdist/dnsdist-protobuf.cc
pdns/dnsdistdist/dnsdist.cc
regression-tests.dnsdist/test_Protobuf.py

index 48fdeefc305655b50d0c74ea32da8475f52a22f2..6f2a9a8b31d4ba9cf16f24917cc0f26914139fb0 100644 (file)
@@ -177,6 +177,7 @@ struct InternalQueryState
   bool useZeroScope{false};
   bool forwardedOverUDP{false};
   bool selfGenerated{false};
+  bool cacheHit{false};
 };
 
 struct IDState
index d3b9200dc7c20e77f4a7fd2ce05db2998306c328..88824c70fbdd4aee3140a57cce3524e5d2f739f0 100644 (file)
@@ -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]
index a72f503508db9ebcd43f30cea17d03a8b20b8a71..481bb87e81428e52bd20dceebac0c116b76df63d 100644 (file)
@@ -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);
index e77d747b81c96245db7b2751a0eed97a973f07dc..8c255d114abb7d7dd1d909cf8f5f3cdd6b755065 100644 (file)
@@ -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'