]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
feat(dnsdist): Also send delayed protobuf for TCP queries
authorPieter Lexis <pieter.lexis@powerdns.com>
Fri, 17 Oct 2025 11:46:16 +0000 (13:46 +0200)
committerPieter Lexis <pieter.lexis@powerdns.com>
Fri, 17 Oct 2025 13:01:27 +0000 (15:01 +0200)
This commit makes some changes to how delayed messages are sent. We now
store the raw, serialized DNSMessage protobuf data in the id-state
object when a send delay is needed.

When the delayed protobuf has to be sent, we generate the OpenTelemetry
Trace data and append it to the message to be sent.

pdns/dnsdistdist/dnsdist-actions-factory.cc
pdns/dnsdistdist/dnsdist-idstate.cc
pdns/dnsdistdist/dnsdist-idstate.hh
pdns/dnsdistdist/dnsdist-protobuf.cc
pdns/dnsdistdist/dnsdist-protobuf.hh
pdns/dnsdistdist/dnsdist.cc

index 610bd4687932c69b3abb0612d598adae4f4e641c..28af79c4ef7d99b8a84eb5661573e81c7ebecdce 100644 (file)
@@ -1861,16 +1861,18 @@ public:
       (*d_alterFunc)(response, &message);
     }
 
+    static thread_local std::string data;
+    data.clear();
+    message.serialize(data, !d_delay);
+
+    if (!response->ids.d_rawProtobufContent.empty()) {
+      data.insert(data.end(), response->ids.d_rawProtobufContent.begin(), response->ids.d_rawProtobufContent.end());
+    }
+
     if (d_delay) {
-      response->ids.delayedResponseMsgs.emplace_back(std::unique_ptr<DNSDistProtoBufMessage>(std::make_unique<DNSDistProtoBufMessage>(message)), std::shared_ptr<RemoteLoggerInterface>(d_logger));
+      response->ids.delayedResponseMsgs.emplace_back(data, std::shared_ptr<RemoteLoggerInterface>(d_logger));
     }
     else {
-      static thread_local std::string data;
-      data.clear();
-      message.serialize(data);
-      if (!response->ids.d_rawProtobufContent.empty()) {
-        data.insert(data.end(), response->ids.d_rawProtobufContent.begin(), response->ids.d_rawProtobufContent.end());
-      }
       d_logger->queueData(data);
     }
 
index 62a108beaad0596034401d9b05d005968ff042ec..30fa8761ec587e2405301548cce4c52f3362073d 100644 (file)
@@ -57,3 +57,26 @@ InternalQueryState InternalQueryState::partialCloneForXFR() const
 #endif
   return ids;
 }
+
+void InternalQueryState::sendDelayedProtobufMessages() const
+{
+#ifndef DISABLE_PROTOBUF
+  static thread_local string otPBBuf;
+  otPBBuf.clear();
+  if (tracingEnabled) {
+    pdns::ProtoZero::Message msg{otPBBuf};
+    msg.setOpenTelemetryData(d_OTTracer->getOTProtobuf());
+  }
+
+  for (auto const& msg_logger : delayedResponseMsgs) {
+    // TODO: we should probably do something with the return value of queueData
+    if (!tracingEnabled) {
+      msg_logger.second->queueData(msg_logger.first);
+      continue;
+    }
+    // Protobuf wireformat allows us to simply append the second "message"
+    // that only contains the OTTrace data as a single bytes field
+    msg_logger.second->queueData(msg_logger.first + otPBBuf);
+  }
+#endif
+}
index 972c4c6f742c6c57f6721e682b5e544d11a7ef30..c802503aaee08c00a334a4eea1ea25c62cde32eb 100644 (file)
@@ -162,6 +162,8 @@ struct InternalQueryState
 #endif /* HAVE_XSK */
   }
 
+  void sendDelayedProtobufMessages() const;
+
   InternalQueryState partialCloneForXFR() const;
 
   boost::optional<Netmask> subnet{boost::none}; // 40
@@ -188,7 +190,7 @@ public:
   std::unique_ptr<PacketBuffer> d_packet{nullptr}; // Initial packet, so we can restart the query from the response path if needed // 8
   std::unique_ptr<ProtoBufData> d_protoBufData{nullptr};
 #ifndef DISABLE_PROTOBUF
-  std::vector<std::pair<std::unique_ptr<DNSDistProtoBufMessage>, std::shared_ptr<RemoteLoggerInterface>>> delayedResponseMsgs;
+  std::vector<std::pair<std::string, std::shared_ptr<RemoteLoggerInterface>>> delayedResponseMsgs;
 #endif
   std::unique_ptr<EDNSExtendedError> d_extendedError{nullptr};
   boost::optional<uint32_t> tempFailureTTL{boost::none}; // 8
index 2f984fc92b7d4fc86e510fd80e4e68bce321c1bd..bb039ef01891c19614019cf08bc7f9909ddb4a90 100644 (file)
@@ -125,7 +125,7 @@ void DNSDistProtoBufMessage::addRR(DNSName&& qname, uint16_t uType, uint16_t uCl
   d_additionalRRs.push_back({std::move(qname), strBlob, uTTL, uType, uClass});
 }
 
-void DNSDistProtoBufMessage::serialize(std::string& data) const
+void DNSDistProtoBufMessage::serialize(std::string& data, bool withOpenTelemetryTraceData) const
 {
   if ((data.capacity() - data.size()) < 128) {
     data.reserve(data.size() + 128);
@@ -247,7 +247,9 @@ void DNSDistProtoBufMessage::serialize(std::string& data) const
 
   if (auto tracer = d_dq.ids.getTracer(); tracer != nullptr && d_dq.ids.tracingEnabled) {
     msg.setOpenTelemetryTraceID(tracer->getTraceID());
-    msg.setOpenTelemetryData(tracer->getOTProtobuf());
+    if (withOpenTelemetryTraceData) {
+      msg.setOpenTelemetryData(tracer->getOTProtobuf());
+    }
   }
 }
 
index 6824c716a37c28e9309e50a7980e1e0e4b3b056c..9b1f56f5953845d3b2a45988be410a3cd572b3aa 100644 (file)
@@ -61,7 +61,7 @@ public:
   void addMeta(const std::string& key, std::vector<std::string>&& strValues, const std::vector<int64_t>& intValues);
   void addRR(DNSName&& qname, uint16_t uType, uint16_t uClass, uint32_t uTTL, const std::string& data);
 
-  void serialize(std::string& data) const;
+  void serialize(std::string& data, bool withOpenTelemetryTraceData = true) const;
 
   [[nodiscard]] std::string toDebugString() const;
 
index 1640d4c1ed3156c3d12de39039bef0cf8d4313bd..b6b8aeaa63d58ca1d90ff38d5749c991b584eb28 100644 (file)
@@ -651,20 +651,7 @@ bool sendUDPResponse(int origFD, const PacketBuffer& response, [[maybe_unused]]
 void handleResponseSent(const InternalQueryState& ids, double udiff, const ComboAddress& client, const ComboAddress& backend, unsigned int size, const dnsheader& cleartextDH, dnsdist::Protocol outgoingProtocol, bool fromBackend)
 {
   handleResponseSent(ids.qname, ids.qtype, udiff, client, backend, size, cleartextDH, outgoingProtocol, ids.protocol, fromBackend);
-
-#ifndef DISABLE_PROTOBUF
-  if (ids.tracingEnabled && !ids.delayedResponseMsgs.empty()) {
-    static thread_local std::string data;
-    for (auto const& msg_logger : ids.delayedResponseMsgs) {
-      data.clear();
-      msg_logger.first->serialize(data);
-      if (!ids.d_rawProtobufContent.empty()) {
-        data.insert(data.end(), ids.d_rawProtobufContent.begin(), ids.d_rawProtobufContent.end());
-      }
-      msg_logger.second->queueData(data);
-    }
-  }
-#endif
+  ids.sendDelayedProtobufMessages();
 }
 
 void handleResponseSent(const DNSName& qname, const QType& qtype, double udiff, const ComboAddress& client, const ComboAddress& backend, unsigned int size, const dnsheader& cleartextDH, dnsdist::Protocol outgoingProtocol, dnsdist::Protocol incomingProtocol, bool fromBackend)