]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: Add an option to export only responses over protobuf 7434/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 30 Jan 2019 10:38:23 +0000 (11:38 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 30 Jan 2019 10:38:23 +0000 (11:38 +0100)
pdns/pdns_recursor.cc
pdns/rec-lua-conf.cc
pdns/rec-lua-conf.hh
pdns/recursordist/docs/lua-config/protobuf.rst
regression-tests.recursor-dnssec/test_Protobuf.py

index 98232dca2924a367a97c8a92f959499ca4b9b910..ce5394e989b8decb62557e4d9575559fe35b372b 100644 (file)
@@ -1548,7 +1548,7 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var)
       if(luaconfsLocal->protobufServer) {
         try {
 
-          if (!luaconfsLocal->protobufTaggedOnly) {
+          if (!luaconfsLocal->protobufResponsesOnly && !luaconfsLocal->protobufTaggedOnly) {
             protobufLogQuery(luaconfsLocal->protobufServer, luaconfsLocal->protobufMaskV4, luaconfsLocal->protobufMaskV6, dc->d_uuid, conn->d_remote, dest, dc->d_ednssubnet.source, true, dh->id, conn->qlen, qname, qtype, qclass, dc->d_policyTags, dc->d_requestorId, dc->d_deviceId);
           }
         }
@@ -1739,7 +1739,7 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr
 #ifdef HAVE_PROTOBUF
     pbMessage.setServerIdentity(SyncRes::s_serverID);
     if(luaconfsLocal->protobufServer) {
-      if (!luaconfsLocal->protobufTaggedOnly || !policyTags.empty()) {
+      if (!luaconfsLocal->protobufResponsesOnly && (!luaconfsLocal->protobufTaggedOnly || !policyTags.empty())) {
         protobufLogQuery(luaconfsLocal->protobufServer, luaconfsLocal->protobufMaskV4, luaconfsLocal->protobufMaskV6, uniqueId, fromaddr, destaddr, ednssubnet.source, false, dh->id, question.size(), qname, qtype, qclass, policyTags, requestorId, deviceId);
       }
     }
index 5e080271a9d1997820eebe9a874a1b22eff3932a..713c7a4f2d7a34800515c0cc3e04fba570ff0172 100644 (file)
@@ -278,7 +278,7 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
     });
 
 #if HAVE_PROTOBUF
-  Lua.writeFunction("protobufServer", [&lci](const string& server_, const boost::optional<uint16_t> timeout, const boost::optional<uint64_t> maxQueuedEntries, const boost::optional<uint8_t> reconnectWaitTime, const boost::optional<uint8_t> maskV4, boost::optional<uint8_t> maskV6, boost::optional<bool> asyncConnect, boost::optional<bool> taggedOnly) {
+  Lua.writeFunction("protobufServer", [&lci](const string& server_, const boost::optional<uint16_t> timeout, const boost::optional<uint64_t> maxQueuedEntries, const boost::optional<uint8_t> reconnectWaitTime, const boost::optional<uint8_t> maskV4, boost::optional<uint8_t> maskV6, boost::optional<bool> asyncConnect, boost::optional<bool> taggedOnly, boost::optional<bool> responsesOnly) {
       try {
        ComboAddress server(server_);
         if (!lci.protobufServer) {
@@ -293,6 +293,9 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de
           if (taggedOnly) {
             lci.protobufTaggedOnly = *taggedOnly;
           }
+          if (responsesOnly) {
+            lci.protobufResponsesOnly = *responsesOnly;
+          }
         }
         else {
           theL()<<Logger::Error<<"Only one protobuf server can be configured, we already have "<<lci.protobufServer->toString()<<endl;
index 6bf2ccdeab68f20afb1227c033f47671f2a3f7d6..7fe78a71f5e9b47d0326af002b5dff5e2a743bed 100644 (file)
@@ -39,6 +39,7 @@ public:
   uint8_t protobufMaskV4{32};
   uint8_t protobufMaskV6{128};
   bool protobufTaggedOnly{false};
+  bool protobufResponsesOnly{false};
 };
 
 extern GlobalStateHolder<LuaConfigItems> g_luaconfs;
index 579a029fc46606e26de7f1581cfffb819029afb1..1bf0f37c79fa6971fd1eb692bf8d5deb6a8188cf 100644 (file)
@@ -12,7 +12,11 @@ Configuring Protocol Buffer logs
 --------------------------------
 Protobuf export to a server is enabled using the ``protobufServer()`` directive:
 
-.. function:: protobufServer(server [[[[[[[, timeout=2], maxQueuedEntries=100], reconnectWaitTime=1], maskV4=32], maskV6=128], asyncConnect=false], taggedOnly=false])
+.. function:: protobufServer(server [[[[[[[[, timeout=2], maxQueuedEntries=100], reconnectWaitTime=1], maskV4=32], maskV6=128], asyncConnect=false], taggedOnly=false], responsesOnly=false])
+
+  .. versionchanged:: 4.1.11
+
+    The optional ``responsesOnly`` parameter was added.
 
   :param string server: The IP and port to connect to
   :param int timeout: Time in seconds to wait when sending a message
@@ -22,6 +26,7 @@ Protobuf export to a server is enabled using the ``protobufServer()`` directive:
   :param int maskV6: Same as maskV4, but for IPv6. Defaults to 128.
   :param bool taggedOnly: Only entries with a policy or a policy tag set will be sent.
   :param bool asyncConnect: When set to false (default) the first connection to the server during startup will block up to ``timeout`` seconds, otherwise the connection is done in a separate thread.
+  :param bool responsesOnly: When set to true, protobuf messages will only be generated for responses, instead of being generated for queries and responses.
 
 Logging outgoing queries and responses
 --------------------------------------
index b58138ddf1e64741d6b3cc1d356247881b3ad038..482b89272900d8417f81ea44d7528a0fb8646f2b 100644 (file)
@@ -391,6 +391,37 @@ auth-zones=example=configs/%s/example.zone""" % _confdir
         self.assertEquals(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.42')
         self.checkNoRemainingMessage()
 
+class ProtobufResponsesOnlyTest(TestRecursorProtobuf):
+    """
+    This test makes sure that we correctly export responses but not queries over protobuf.
+    """
+
+    _confdir = 'ProtobufResponsesOnly'
+    _config_template = """
+auth-zones=example=configs/%s/example.zone""" % _confdir
+    _lua_config_file = """
+    protobufServer("127.0.0.1:%d", 2, 100, 1, 32, 128, false, false, true)
+    """ % (protobufServersParameters[0].port)
+
+    def testA(self):
+        name = 'a.example.'
+        expected = dns.rrset.from_text(name, 0, dns.rdataclass.IN, 'A', '192.0.2.42')
+        query = dns.message.make_query(name, 'A', want_dnssec=True)
+        query.flags |= dns.flags.CD
+        res = self.sendUDPQuery(query)
+        self.assertRRsetInAnswer(res, expected)
+
+        # check the protobuf message corresponding to the UDP response
+        msg = self.getFirstProtobufMessage()
+        self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.UDP, res)
+        self.assertEquals(len(msg.response.rrs), 1)
+        rr = msg.response.rrs[0]
+        # we have max-cache-ttl set to 15
+        self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15)
+        self.assertEquals(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.42')
+        # nothing else in the queue
+        self.checkNoRemainingMessage()
+
 class ProtobufTaggedOnlyTest(TestRecursorProtobuf):
     """
     This test makes sure that we correctly export queries and responses but only if they have been tagged.