From f7ddeb093caf549ea8a1dc758e462a66df7cadb9 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 30 Jan 2019 11:38:23 +0100 Subject: [PATCH] rec: Add an option to export only responses over protobuf --- pdns/pdns_recursor.cc | 4 +-- pdns/rec-lua-conf.cc | 5 ++- pdns/rec-lua-conf.hh | 1 + .../recursordist/docs/lua-config/protobuf.rst | 7 ++++- .../test_Protobuf.py | 31 +++++++++++++++++++ 5 files changed, 44 insertions(+), 4 deletions(-) diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 98232dca29..ce5394e989 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -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); } } diff --git a/pdns/rec-lua-conf.cc b/pdns/rec-lua-conf.cc index 5e080271a9..713c7a4f2d 100644 --- a/pdns/rec-lua-conf.cc +++ b/pdns/rec-lua-conf.cc @@ -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 timeout, const boost::optional maxQueuedEntries, const boost::optional reconnectWaitTime, const boost::optional maskV4, boost::optional maskV6, boost::optional asyncConnect, boost::optional taggedOnly) { + Lua.writeFunction("protobufServer", [&lci](const string& server_, const boost::optional timeout, const boost::optional maxQueuedEntries, const boost::optional reconnectWaitTime, const boost::optional maskV4, boost::optional maskV6, boost::optional asyncConnect, boost::optional taggedOnly, boost::optional 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()<toString()< g_luaconfs; diff --git a/pdns/recursordist/docs/lua-config/protobuf.rst b/pdns/recursordist/docs/lua-config/protobuf.rst index 579a029fc4..1bf0f37c79 100644 --- a/pdns/recursordist/docs/lua-config/protobuf.rst +++ b/pdns/recursordist/docs/lua-config/protobuf.rst @@ -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 -------------------------------------- diff --git a/regression-tests.recursor-dnssec/test_Protobuf.py b/regression-tests.recursor-dnssec/test_Protobuf.py index b58138ddf1..482b892729 100644 --- a/regression-tests.recursor-dnssec/test_Protobuf.py +++ b/regression-tests.recursor-dnssec/test_Protobuf.py @@ -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. -- 2.47.2