]> granicus.if.org Git - pdns/commitdiff
rec: Add 'protobuf-use-kernel-timestamp' for sharper latencies
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 21 Feb 2019 15:06:21 +0000 (16:06 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 25 Mar 2019 09:24:30 +0000 (10:24 +0100)
pdns/pdns_recursor.cc
pdns/recursordist/docs/settings.rst

index b8d1f8ade5e1a98c9c62ff27bfa7abbdd4aafe38..ca47663b29b1a24dcdcb2aaaca3a159d19d90278 100644 (file)
@@ -208,6 +208,7 @@ static bool g_reusePort{false};
 static bool g_gettagNeedsEDNSOptions{false};
 static time_t g_statisticsInterval;
 static bool g_useIncomingECS;
+static bool g_useKernelTimestamp;
 std::atomic<uint32_t> g_maxCacheEntries, g_maxPacketCacheEntries;
 #ifdef NOD_ENABLED
 static bool g_nodEnabled;
@@ -308,6 +309,7 @@ struct DNSComboWriter {
   boost::uuids::uuid d_uuid;
   string d_requestorId;
   string d_deviceId;
+  struct timeval d_kernelTimestamp{0,0};
 #endif
   std::string d_query;
   std::vector<std::string> d_policyTags;
@@ -1534,7 +1536,12 @@ static void startDoResolve(void *p)
         pbMessage->setAppliedPolicyType(appliedPolicy.d_type);
       }
       pbMessage->setPolicyTags(dc->d_policyTags);
-      pbMessage->setQueryTime(dc->d_now.tv_sec, dc->d_now.tv_usec);
+      if (g_useKernelTimestamp && dc->d_kernelTimestamp.tv_sec) {
+        pbMessage->setQueryTime(dc->d_kernelTimestamp.tv_sec, dc->d_kernelTimestamp.tv_usec);
+      }
+      else {
+        pbMessage->setQueryTime(dc->d_now.tv_sec, dc->d_now.tv_usec);
+      }
       pbMessage->setRequestorId(dq.requestorId);
       pbMessage->setDeviceId(dq.deviceId);
 #ifdef NOD_ENABLED
@@ -2058,12 +2065,14 @@ static void handleNewTCPQuestion(int fd, FDMultiplexer::funcparam_t& )
 static string* doProcessUDPQuestion(const std::string& question, const ComboAddress& fromaddr, const ComboAddress& destaddr, struct timeval tv, int fd)
 {
   gettimeofday(&g_now, 0);
-  struct timeval diff = g_now - tv;
-  double delta=(diff.tv_sec*1000 + diff.tv_usec/1000.0);
+  if (tv.tv_sec) {
+    struct timeval diff = g_now - tv;
+    double delta=(diff.tv_sec*1000 + diff.tv_usec/1000.0);
 
-  if(tv.tv_sec && delta > 1000.0) {
-    g_stats.tooOldDrops++;
-    return 0;
+    if(delta > 1000.0) {
+      g_stats.tooOldDrops++;
+      return nullptr;
+    }
   }
 
   ++g_stats.qcounter;
@@ -2193,7 +2202,12 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr
         const ComboAddress& requestor = requestorNM.getMaskedNetwork();
         pbMessage->update(uniqueId, &requestor, &destination, false, dh->id);
         pbMessage->setEDNSSubnet(ednssubnet.source, ednssubnet.source.isIpv4() ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6);
-        pbMessage->setQueryTime(g_now.tv_sec, g_now.tv_usec);
+        if (g_useKernelTimestamp && tv.tv_sec) {
+          pbMessage->setQueryTime(tv.tv_sec, tv.tv_usec);
+        }
+        else {
+          pbMessage->setQueryTime(g_now.tv_sec, g_now.tv_usec);
+        }
         pbMessage->setRequestorId(requestorId);
         pbMessage->setDeviceId(deviceId);
         protobufLogResponse(*pbMessage);
@@ -2271,6 +2285,7 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr
   }
   dc->d_requestorId = requestorId;
   dc->d_deviceId = deviceId;
+  dc->d_kernelTimestamp = tv;
 #endif
 
   MT->makeThread(startDoResolve, (void*) dc.release()); // deletes dc
@@ -3859,6 +3874,8 @@ static int serviceMain(int argc, char*argv[])
   g_tcpMaxQueriesPerConn=::arg().asNum("max-tcp-queries-per-connection");
   s_maxUDPQueriesPerRound=::arg().asNum("max-udp-queries-per-round");
 
+  g_useKernelTimestamp = ::arg().mustDo("protobuf-use-kernel-timestamp");
+
   blacklistStats(StatComponent::API, ::arg()["stats-api-blacklist"]);
   blacklistStats(StatComponent::Carbon, ::arg()["stats-carbon-blacklist"]);
   blacklistStats(StatComponent::RecControl, ::arg()["stats-rec-control-blacklist"]);
@@ -4280,6 +4297,7 @@ int main(int argc, char **argv)
     ::arg().set("max-total-msec", "Maximum total wall-clock time per query in milliseconds, 0 for unlimited")="7000";
     ::arg().set("max-recursion-depth", "Maximum number of internal recursion calls per query, 0 for unlimited")="40";
     ::arg().set("max-udp-queries-per-round", "Maximum number of UDP queries processed per recvmsg() round, before returning back to normal processing")="10000";
+    ::arg().set("protobuf-use-kernel-timestamp", "Compute the latency of queries in protobuf messages by using the timestamp set by the kernel when the query was received (when available)")="";
 
     ::arg().set("include-dir","Include *.conf files from this directory")="";
     ::arg().set("security-poll-suffix","Domain name from which to query security update notifications")="secpoll.powerdns.com.";
index 5d9b529bfba408e4af43b8c375a41faefe1811de..f76a990e06477ce8c74ec5da2aa2099a674715d1 100644 (file)
@@ -1038,6 +1038,17 @@ maximizing the cache hit ratio. Starting with version 4.2.0, more than one distr
 setting.
 Improves performance on Linux.
 
+.. _settting-protobuf-use-kernel-timestamp:
+
+``protobuf-use-kernel-timestamp``
+---------------------------
+.. versionadded:: 4.2.0
+
+- Boolean
+- Default: false
+
+Whether to compute the latency of responses in protobuf messages using the timestamp set by the kernel when the query packet was received (when available), instead of computing it based on the moment we start processing the query.
+
 .. _settting-public-suffix-list-file:
 
 ``public-suffix-list-file``