From e3381435870e89c8573efb4a44497a08b0807b24 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 25 Sep 2025 12:01:52 +0200 Subject: [PATCH] dnsdist: Fix setting meta keys on response, pass them from question to response This commit fixes setting Protocol Buffer meta keys on DNS response via Lua FFI: the existing code was assuming it was possible to use the question methods on a response object which is not true and would likely have ended in a crash at some point. It also propates meta keys set on a DNS question to the corresponding DNS response. Before this commit the values were not passed along to the response which was quite unexpected, especially for self-answered responses. Signed-off-by: Remi Gacogne --- pdns/dnsdistdist/dnsdist-actions-factory.cc | 8 +- pdns/dnsdistdist/dnsdist-idstate.cc | 3 + pdns/dnsdistdist/dnsdist-idstate.hh | 3 + .../dnsdist-lua-bindings-dnsquestion.cc | 2 +- pdns/dnsdistdist/dnsdist-lua-ffi-interface.h | 9 +++ pdns/dnsdistdist/dnsdist-lua-ffi.cc | 78 ++++++++++++++++++- pdns/dnsdistdist/dnsdist-lua-ffi.hh | 11 ++- pdns/dnsdistdist/dnsdist.hh | 3 - pdns/dnsdistdist/docs/reference/dq.rst | 3 + pdns/dnsdistdist/test-dnsdist-lua-ffi.cc | 38 ++++++++- regression-tests.dnsdist/test_Protobuf.py | 59 +++++++++----- 11 files changed, 182 insertions(+), 35 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-actions-factory.cc b/pdns/dnsdistdist/dnsdist-actions-factory.cc index db27eb063a..320428d276 100644 --- a/pdns/dnsdistdist/dnsdist-actions-factory.cc +++ b/pdns/dnsdistdist/dnsdist-actions-factory.cc @@ -1637,8 +1637,8 @@ public: static thread_local std::string data; data.clear(); message.serialize(data); - if (!dnsquestion->d_rawProtobufContent.empty()) { - data.insert(data.end(), dnsquestion->d_rawProtobufContent.begin(), dnsquestion->d_rawProtobufContent.end()); + if (!dnsquestion->ids.d_rawProtobufContent.empty()) { + data.insert(data.end(), dnsquestion->ids.d_rawProtobufContent.begin(), dnsquestion->ids.d_rawProtobufContent.end()); } remoteLoggerQueueData(*d_logger, data); @@ -1801,8 +1801,8 @@ public: static thread_local std::string data; data.clear(); message.serialize(data); - if (!response->d_rawProtobufContent.empty()) { - data.insert(data.end(), response->d_rawProtobufContent.begin(), response->d_rawProtobufContent.end()); + if (!response->ids.d_rawProtobufContent.empty()) { + data.insert(data.end(), response->ids.d_rawProtobufContent.begin(), response->ids.d_rawProtobufContent.end()); } d_logger->queueData(data); diff --git a/pdns/dnsdistdist/dnsdist-idstate.cc b/pdns/dnsdistdist/dnsdist-idstate.cc index 3217720a58..62a108beaa 100644 --- a/pdns/dnsdistdist/dnsdist-idstate.cc +++ b/pdns/dnsdistdist/dnsdist-idstate.cc @@ -52,5 +52,8 @@ InternalQueryState InternalQueryState::partialCloneForXFR() const ids.cs = cs; /* in case we want to support XFR over DoH, or the stream ID becomes used for QUIC */ ids.d_streamID = d_streamID; +#if !defined(DISABLE_PROTOBUF) + ids.d_rawProtobufContent = d_rawProtobufContent; +#endif return ids; } diff --git a/pdns/dnsdistdist/dnsdist-idstate.hh b/pdns/dnsdistdist/dnsdist-idstate.hh index 10e2412051..74839e2d69 100644 --- a/pdns/dnsdistdist/dnsdist-idstate.hh +++ b/pdns/dnsdistdist/dnsdist-idstate.hh @@ -131,6 +131,9 @@ struct InternalQueryState boost::optional subnet{boost::none}; // 40 std::string poolName; // 32 +#if !defined(DISABLE_PROTOBUF) + std::string d_rawProtobufContent; // protobuf-encoded content to add to protobuf messages // 32 +#endif /* DISABLE_PROTOBUF */ ComboAddress origRemote; // 28 ComboAddress origDest; // 28 ComboAddress hopRemote; diff --git a/pdns/dnsdistdist/dnsdist-lua-bindings-dnsquestion.cc b/pdns/dnsdistdist/dnsdist-lua-bindings-dnsquestion.cc index 458acd10cc..e3b37f271a 100644 --- a/pdns/dnsdistdist/dnsdist-lua-bindings-dnsquestion.cc +++ b/pdns/dnsdistdist/dnsdist-lua-bindings-dnsquestion.cc @@ -34,7 +34,7 @@ static void addMetaKeyAndValuesToProtobufContent([[maybe_unused]] DNSQuestion& dnsQuestion, [[maybe_unused]] const std::string& key, [[maybe_unused]] const LuaArray>& values) { #if !defined(DISABLE_PROTOBUF) - protozero::pbf_writer pbfWriter{dnsQuestion.d_rawProtobufContent}; + protozero::pbf_writer pbfWriter{dnsQuestion.ids.d_rawProtobufContent}; protozero::pbf_writer pbfMetaWriter{pbfWriter, static_cast(pdns::ProtoZero::Message::Field::meta)}; pbfMetaWriter.add_string(static_cast(pdns::ProtoZero::Message::MetaField::key), key); protozero::pbf_writer pbfMetaValueWriter{pbfMetaWriter, static_cast(pdns::ProtoZero::Message::MetaField::value)}; diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h b/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h index dfbce92621..f5a7602496 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h +++ b/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h @@ -319,3 +319,12 @@ void dnsdist_ffi_dnsquestion_meta_add_str_value_to_key(dnsdist_ffi_dnsquestion_t void dnsdist_ffi_dnsquestion_meta_add_int64_value_to_key(dnsdist_ffi_dnsquestion_t* dnsQuestion, int64_t value) __attribute__ ((visibility ("default"))); /* this function should never be called if dnsdist_ffi_dnsquestion_meta_begin_key has not been called first */ void dnsdist_ffi_dnsquestion_meta_end_key(dnsdist_ffi_dnsquestion_t* dnsQuestion) __attribute__ ((visibility ("default"))); + +/* this function adds a new key to the raw meta buffer. It can only be called with the same key on a given query once, and dnsdist_ffi_dnsresponse_meta_end_key should always be called after values have been added */ +void dnsdist_ffi_dnsresponse_meta_begin_key(dnsdist_ffi_dnsresponse_t* dnsResponse, const char* key, size_t keyLen) __attribute__ ((visibility ("default"))); +/* this function should never be called if dnsdist_ffi_dnsresponse_meta_begin_key has not been called first */ +void dnsdist_ffi_dnsresponse_meta_add_str_value_to_key(dnsdist_ffi_dnsresponse_t* dnsResponse, const char* value, size_t valueLen) __attribute__ ((visibility ("default"))); +/* this function should never be called if dnsdist_ffi_dnsresponse_meta_begin_key has not been called first */ +void dnsdist_ffi_dnsresponse_meta_add_int64_value_to_key(dnsdist_ffi_dnsresponse_t* dnsResponse, int64_t value) __attribute__ ((visibility ("default"))); +/* this function should never be called if dnsdist_ffi_dnsresponse_meta_begin_key has not been called first */ +void dnsdist_ffi_dnsresponse_meta_end_key(dnsdist_ffi_dnsresponse_t* dnsResponse) __attribute__ ((visibility ("default"))); diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi.cc b/pdns/dnsdistdist/dnsdist-lua-ffi.cc index 439beb8851..9492361c34 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/dnsdist-lua-ffi.cc @@ -2370,7 +2370,7 @@ void dnsdist_ffi_dnsquestion_meta_begin_key([[maybe_unused]] dnsdist_ffi_dnsques return; } - dnsQuestion->pbfWriter = protozero::pbf_writer{dnsQuestion->dq->d_rawProtobufContent}; + dnsQuestion->pbfWriter = protozero::pbf_writer{dnsQuestion->dq->ids.d_rawProtobufContent}; dnsQuestion->pbfMetaWriter = protozero::pbf_writer{dnsQuestion->pbfWriter, static_cast(pdns::ProtoZero::Message::Field::meta)}; dnsQuestion->pbfMetaWriter.add_string(static_cast(pdns::ProtoZero::Message::MetaField::key), protozero::data_view(key, keyLen)); dnsQuestion->pbfMetaValueWriter = protozero::pbf_writer {dnsQuestion->pbfMetaWriter, static_cast(pdns::ProtoZero::Message::MetaField::value)}; @@ -2415,6 +2415,7 @@ void dnsdist_ffi_dnsquestion_meta_end_key([[maybe_unused]] dnsdist_ffi_dnsquesti if (dnsQuestion == nullptr) { return; } + if (!dnsQuestion->pbfWriter.valid()) { vinfolog("Error in dnsdist_ffi_dnsquestion_meta_end_key: trying to end a key that has not been started"); return; @@ -2431,3 +2432,78 @@ void dnsdist_ffi_dnsquestion_meta_end_key([[maybe_unused]] dnsdist_ffi_dnsquesti } #endif /* DISABLE_PROTOBUF */ } + +void dnsdist_ffi_dnsresponse_meta_begin_key([[maybe_unused]] dnsdist_ffi_dnsresponse_t* dnsResponse, [[maybe_unused]] const char* key, [[maybe_unused]] size_t keyLen) +{ +#if !defined(DISABLE_PROTOBUF) + if (dnsResponse == nullptr || key == nullptr || keyLen == 0) { + return; + } + + if (dnsResponse->pbfWriter.valid()) { + vinfolog("Error in dnsdist_ffi_dnsresponse_meta_begin_key: the previous key has not been ended"); + return; + } + + dnsResponse->pbfWriter = protozero::pbf_writer{dnsResponse->dr->ids.d_rawProtobufContent}; + dnsResponse->pbfMetaWriter = protozero::pbf_writer{dnsResponse->pbfWriter, static_cast(pdns::ProtoZero::Message::Field::meta)}; + dnsResponse->pbfMetaWriter.add_string(static_cast(pdns::ProtoZero::Message::MetaField::key), protozero::data_view(key, keyLen)); + dnsResponse->pbfMetaValueWriter = protozero::pbf_writer {dnsResponse->pbfMetaWriter, static_cast(pdns::ProtoZero::Message::MetaField::value)}; +#endif /* DISABLE_PROTOBUF */ +} + +void dnsdist_ffi_dnsresponse_meta_add_str_value_to_key([[maybe_unused]] dnsdist_ffi_dnsresponse_t* dnsResponse, [[maybe_unused]] const char* value, [[maybe_unused]] size_t valueLen) +{ +#if !defined(DISABLE_PROTOBUF) + if (dnsResponse == nullptr || value == nullptr || valueLen == 0) { + return; + } + + if (!dnsResponse->pbfMetaValueWriter.valid()) { + vinfolog("Error in dnsdist_ffi_dnsresponse_meta_add_str_value_to_key: trying to add a value without starting a key"); + return; + } + + dnsResponse->pbfMetaValueWriter.add_string(static_cast(pdns::ProtoZero::Message::MetaValueField::stringVal), protozero::data_view(value, valueLen)); +#endif /* DISABLE_PROTOBUF */ +} + +void dnsdist_ffi_dnsresponse_meta_add_int64_value_to_key([[maybe_unused]] dnsdist_ffi_dnsresponse_t* dnsResponse, [[maybe_unused]] int64_t value) +{ +#if !defined(DISABLE_PROTOBUF) + if (dnsResponse == nullptr) { + return; + } + + if (!dnsResponse->pbfMetaValueWriter.valid()) { + vinfolog("Error in dnsdist_ffi_dnsresponse_meta_add_int64_value_to_key: trying to add a value without starting a key"); + return; + } + + dnsResponse->pbfMetaValueWriter.add_uint64(static_cast(pdns::ProtoZero::Message::MetaValueField::intVal), value); +#endif /* DISABLE_PROTOBUF */ +} + +void dnsdist_ffi_dnsresponse_meta_end_key([[maybe_unused]] dnsdist_ffi_dnsresponse_t* dnsResponse) +{ +#if !defined(DISABLE_PROTOBUF) + if (dnsResponse == nullptr) { + return; + } + + if (!dnsResponse->pbfWriter.valid()) { + vinfolog("Error in dnsdist_ffi_dnsresponse_meta_end_key: trying to end a key that has not been started"); + return; + } + + try { + /* reset the pbf writer so that the sizes are properly updated */ + dnsResponse->pbfMetaValueWriter.commit(); + dnsResponse->pbfMetaWriter.commit(); + dnsResponse->pbfWriter = protozero::pbf_writer(); + } + catch (const std::exception& exp) { + vinfolog("Error in dnsdist_ffi_dnsresponse_meta_end_key: %s", exp.what()); + } +#endif /* DISABLE_PROTOBUF */ +} diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi.hh b/pdns/dnsdistdist/dnsdist-lua-ffi.hh index 3fc30f13e5..40a0535879 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi.hh +++ b/pdns/dnsdistdist/dnsdist-lua-ffi.hh @@ -66,9 +66,9 @@ struct dnsdist_ffi_dnsquestion_t std::unique_ptr> proxyProtocolValuesVect; std::unique_ptr> httpHeaders; #if !defined(DISABLE_PROTOBUF) - protozero::pbf_writer pbfWriter; - protozero::pbf_writer pbfMetaWriter; - protozero::pbf_writer pbfMetaValueWriter; + protozero::pbf_writer pbfWriter{}; + protozero::pbf_writer pbfMetaWriter{}; + protozero::pbf_writer pbfMetaValueWriter{}; #endif /* DISABLE_PROTOBUF */ }; @@ -95,6 +95,11 @@ struct dnsdist_ffi_dnsresponse_t DNSResponse* dr{nullptr}; std::optional result{std::nullopt}; +#if !defined(DISABLE_PROTOBUF) + protozero::pbf_writer pbfWriter{}; + protozero::pbf_writer pbfMetaWriter{}; + protozero::pbf_writer pbfMetaValueWriter{}; +#endif /* DISABLE_PROTOBUF */ }; // dnsdist_ffi_server_t is a lightuserdata diff --git a/pdns/dnsdistdist/dnsdist.hh b/pdns/dnsdistdist/dnsdist.hh index d3cefa56c3..09359a6289 100644 --- a/pdns/dnsdistdist/dnsdist.hh +++ b/pdns/dnsdistdist/dnsdist.hh @@ -176,9 +176,6 @@ public: InternalQueryState& ids; std::unique_ptr ecs{nullptr}; std::string sni; /* Server Name Indication, if any (DoT or DoH) */ -#if !defined(DISABLE_PROTOBUF) - std::string d_rawProtobufContent; /* protobuf-encoded content to add to protobuf messages */ -#endif /* DISABLE_PROTOBUF */ mutable std::unique_ptr ednsOptions; /* this needs to be mutable because it is parsed just in time, when DNSQuestion is read-only */ std::shared_ptr d_incomingTCPState{nullptr}; std::unique_ptr> proxyProtocolValues{nullptr}; diff --git a/pdns/dnsdistdist/docs/reference/dq.rst b/pdns/dnsdistdist/docs/reference/dq.rst index e0bc2d0dbf..8de096e374 100644 --- a/pdns/dnsdistdist/docs/reference/dq.rst +++ b/pdns/dnsdistdist/docs/reference/dq.rst @@ -325,6 +325,9 @@ This state can be modified from the various hooks. .. versionadded:: 2.0.0 + .. versionchanged:: 2.0.2 + Prior to 2.0.2 meta-data entries were not propagated from questions to responses, which was especially unexpected for self-answered responses. + Set a meta-data entry to be exported in the ``meta`` field of ProtoBuf messages. :param string key: The key diff --git a/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc b/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc index ca49f6453d..0d7cee13c3 100644 --- a/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc @@ -1053,6 +1053,8 @@ BOOST_AUTO_TEST_CASE(test_meta_values) DNSQuestion dnsQuestion(ids, query); dnsdist_ffi_dnsquestion_t lightDQ(&dnsQuestion); + DNSResponse dnsResponse(ids, query, nullptr); + dnsdist_ffi_dnsresponse_t lightDR(&dnsResponse); { /* check invalid parameters */ @@ -1064,18 +1066,28 @@ BOOST_AUTO_TEST_CASE(test_meta_values) dnsdist_ffi_dnsquestion_meta_add_str_value_to_key(&lightDQ, "some-str-value", 0); dnsdist_ffi_dnsquestion_meta_add_int64_value_to_key(nullptr, 0); dnsdist_ffi_dnsquestion_meta_end_key(nullptr); + + dnsdist_ffi_dnsresponse_meta_begin_key(nullptr, nullptr, 0); + dnsdist_ffi_dnsresponse_meta_begin_key(&lightDR, nullptr, 0); + dnsdist_ffi_dnsresponse_meta_begin_key(&lightDR, "some-key", 0); + dnsdist_ffi_dnsresponse_meta_add_str_value_to_key(nullptr, nullptr, 0); + dnsdist_ffi_dnsresponse_meta_add_str_value_to_key(&lightDR, nullptr, 0); + dnsdist_ffi_dnsresponse_meta_add_str_value_to_key(&lightDR, "some-str-value", 0); + dnsdist_ffi_dnsresponse_meta_add_int64_value_to_key(nullptr, 0); + dnsdist_ffi_dnsresponse_meta_end_key(nullptr); } { /* trying to end a key that has not been started */ dnsdist_ffi_dnsquestion_meta_end_key(&lightDQ); + dnsdist_ffi_dnsresponse_meta_end_key(&lightDR); } { const std::string key{"some-key"}; const std::string value1{"first value"}; const std::string value2{"second value"}; - BOOST_CHECK_EQUAL(dnsQuestion.d_rawProtobufContent.size(), 0U); + BOOST_CHECK_EQUAL(dnsQuestion.ids.d_rawProtobufContent.size(), 0U); dnsdist_ffi_dnsquestion_meta_begin_key(&lightDQ, key.data(), key.size()); /* we should not be able to begin a new key without ending it first */ dnsdist_ffi_dnsquestion_meta_begin_key(&lightDQ, key.data(), key.size()); @@ -1084,8 +1096,28 @@ BOOST_AUTO_TEST_CASE(test_meta_values) dnsdist_ffi_dnsquestion_meta_add_str_value_to_key(&lightDQ, value2.data(), value2.size()); dnsdist_ffi_dnsquestion_meta_add_int64_value_to_key(&lightDQ, -42); dnsdist_ffi_dnsquestion_meta_end_key(&lightDQ); - BOOST_CHECK_EQUAL(dnsQuestion.d_rawProtobufContent.size(), 55U); - BOOST_CHECK_EQUAL(Base64Encode(dnsQuestion.d_rawProtobufContent), "sgE0Cghzb21lLWtleRIoCgtmaXJzdCB2YWx1ZRAqCgxzZWNvbmQgdmFsdWUQ1v//////////AQ=="); + BOOST_CHECK_EQUAL(dnsQuestion.ids.d_rawProtobufContent.size(), 55U); + BOOST_CHECK_EQUAL(Base64Encode(dnsQuestion.ids.d_rawProtobufContent), "sgE0Cghzb21lLWtleRIoCgtmaXJzdCB2YWx1ZRAqCgxzZWNvbmQgdmFsdWUQ1v//////////AQ=="); + BOOST_CHECK_EQUAL(dnsResponse.ids.d_rawProtobufContent.size(), 55U); + BOOST_CHECK_EQUAL(Base64Encode(dnsResponse.ids.d_rawProtobufContent), "sgE0Cghzb21lLWtleRIoCgtmaXJzdCB2YWx1ZRAqCgxzZWNvbmQgdmFsdWUQ1v//////////AQ=="); + } + + { + const std::string key{"some-key"}; + const std::string value1{"first value"}; + const std::string value2{"second value"}; + /* be careful: IDS is shared with the DNS question */ + dnsResponse.ids.d_rawProtobufContent.clear(); + dnsdist_ffi_dnsresponse_meta_begin_key(&lightDR, key.data(), key.size()); + /* we should not be able to begin a new key without ending it first */ + dnsdist_ffi_dnsresponse_meta_begin_key(&lightDR, key.data(), key.size()); + dnsdist_ffi_dnsresponse_meta_add_str_value_to_key(&lightDR, value1.data(), value1.size()); + dnsdist_ffi_dnsresponse_meta_add_int64_value_to_key(&lightDR, 42); + dnsdist_ffi_dnsresponse_meta_add_str_value_to_key(&lightDR, value2.data(), value2.size()); + dnsdist_ffi_dnsresponse_meta_add_int64_value_to_key(&lightDR, -42); + dnsdist_ffi_dnsresponse_meta_end_key(&lightDR); + BOOST_CHECK_EQUAL(dnsResponse.ids.d_rawProtobufContent.size(), 55U); + BOOST_CHECK_EQUAL(Base64Encode(dnsResponse.ids.d_rawProtobufContent), "sgE0Cghzb21lLWtleRIoCgtmaXJzdCB2YWx1ZRAqCgxzZWNvbmQgdmFsdWUQ1v//////////AQ=="); } } #endif /* DISABLE_PROTOBUF */ diff --git a/regression-tests.dnsdist/test_Protobuf.py b/regression-tests.dnsdist/test_Protobuf.py index f5717ad3af..eb51483961 100644 --- a/regression-tests.dnsdist/test_Protobuf.py +++ b/regression-tests.dnsdist/test_Protobuf.py @@ -423,35 +423,42 @@ class TestProtobufMetaTags(DNSDistProtobufTest): local ffi = require("ffi") local C = ffi.C - function add_meta(dq) + function add_meta_to_query(dq) local key = "my-meta-key-1" - local key2 = "my-meta-key-2" C.dnsdist_ffi_dnsquestion_meta_begin_key(dq, key, #key) C.dnsdist_ffi_dnsquestion_meta_add_str_value_to_key(dq, "test", 4) C.dnsdist_ffi_dnsquestion_meta_add_int64_value_to_key(dq, -42) C.dnsdist_ffi_dnsquestion_meta_add_str_value_to_key(dq, "test2", 5) C.dnsdist_ffi_dnsquestion_meta_end_key(dq) + return DNSAction.None + end + function add_meta_to_response(dr) local key2 = "my-meta-key-2" - C.dnsdist_ffi_dnsquestion_meta_begin_key(dq, key2, #key2) - C.dnsdist_ffi_dnsquestion_meta_add_str_value_to_key(dq, "foo", 3) - C.dnsdist_ffi_dnsquestion_meta_add_int64_value_to_key(dq, 42) - C.dnsdist_ffi_dnsquestion_meta_add_str_value_to_key(dq, "bar", 3) - C.dnsdist_ffi_dnsquestion_meta_end_key(dq) + C.dnsdist_ffi_dnsresponse_meta_begin_key(dr, key2, #key2) + C.dnsdist_ffi_dnsresponse_meta_add_str_value_to_key(dr, "foo", 3) + C.dnsdist_ffi_dnsresponse_meta_add_int64_value_to_key(dr, 42) + C.dnsdist_ffi_dnsresponse_meta_add_str_value_to_key(dr, "bar", 3) + C.dnsdist_ffi_dnsresponse_meta_end_key(dr) + return DNSResponseAction.None + end + function addMetaToQuery(dq) + dq:setMetaKey('my-meta-key-3', {'test', -42, 'test2'}) return DNSAction.None end function addMetaToResponse(dr) - dr:setMetaKey('my-meta-key-1', {'test', -42, 'test2'}) - dr:setMetaKey('my-meta-key-2', {'foo', 42, 'bar'}) + dr:setMetaKey('my-meta-key-4', {'foo', 42, 'bar'}) return DNSResponseAction.None end - addAction(AllRule(), LuaFFIAction(add_meta)) + addAction(AllRule(), LuaFFIAction(add_meta_to_query)) addAction(AllRule(), SetTagAction('my-tag-key', 'my-tag-value')) addAction(AllRule(), SetTagAction('my-empty-key', '')) + addAction(AllRule(), LuaAction(addMetaToQuery)) addAction(AllRule(), RemoteLogAction(rl, nil, {serverID='dnsdist-server-1', exportTags='*'}, {b64='b64-content', ['my-tag-export-name']='tag:my-tag-key'})) + addResponseAction(AllRule(), LuaFFIResponseAction(add_meta_to_response)) addResponseAction(AllRule(), LuaResponseAction(addMetaToResponse)) addResponseAction(AllRule(), SetTagResponseAction('my-tag-key2', 'my-tag-value2')) addResponseAction(AllRule(), RemoteLogResponseAction(rl, nil, false, {serverID='dnsdist-server-1', exportTags='my-empty-key,my-tag-key2'}, {['my-tag-export-name']='tags'})) @@ -505,11 +512,11 @@ class TestProtobufMetaTags(DNSDistProtobufTest): self.assertIn('test2', msg.meta[2].value.stringVal) self.assertIn(-42, msg.meta[2].value.intVal) - self.assertEqual(msg.meta[3].key, 'my-meta-key-2') - self.assertEqual(len(msg.meta[3].value.stringVal), 2) - self.assertIn('foo', msg.meta[3].value.stringVal) - self.assertIn('bar', msg.meta[3].value.stringVal) - self.assertIn(42, msg.meta[3].value.intVal) + self.assertEqual(msg.meta[3].key, 'my-meta-key-3') + self.assertEqual(len(msg.meta[2].value.stringVal), 2) + self.assertIn('test', msg.meta[2].value.stringVal) + self.assertIn('test2', msg.meta[2].value.stringVal) + self.assertIn(-42, msg.meta[2].value.intVal) b64EncodedQuery = base64.b64encode(query.to_wire()).decode('ascii') self.assertEqual(tags['b64'], [b64EncodedQuery]) @@ -523,7 +530,7 @@ class TestProtobufMetaTags(DNSDistProtobufTest): self.assertIn('my-tag-key2:my-tag-value2', msg.response.tags) self.assertIn('my-empty-key', msg.response.tags) # meta tags - self.assertEqual(len(msg.meta), 3) + self.assertEqual(len(msg.meta), 5) self.assertEqual(msg.meta[0].key, 'my-tag-export-name') self.assertEqual(len(msg.meta[0].value.stringVal), 3) self.assertIn('my-tag-key:my-tag-value', msg.meta[0].value.stringVal) @@ -537,11 +544,23 @@ class TestProtobufMetaTags(DNSDistProtobufTest): self.assertIn('test2', msg.meta[1].value.stringVal) self.assertIn(-42, msg.meta[1].value.intVal) - self.assertEqual(msg.meta[2].key, 'my-meta-key-2') + self.assertEqual(msg.meta[2].key, 'my-meta-key-3') self.assertEqual(len(msg.meta[2].value.stringVal), 2) - self.assertIn('foo', msg.meta[2].value.stringVal) - self.assertIn('bar', msg.meta[2].value.stringVal) - self.assertIn(42, msg.meta[2].value.intVal) + self.assertIn('test', msg.meta[2].value.stringVal) + self.assertIn('test2', msg.meta[2].value.stringVal) + self.assertIn(-42, msg.meta[2].value.intVal) + + self.assertEqual(msg.meta[3].key, 'my-meta-key-2') + self.assertEqual(len(msg.meta[3].value.stringVal), 2) + self.assertIn('foo', msg.meta[3].value.stringVal) + self.assertIn('bar', msg.meta[3].value.stringVal) + self.assertIn(42, msg.meta[3].value.intVal) + + self.assertEqual(msg.meta[4].key, 'my-meta-key-4') + self.assertEqual(len(msg.meta[4].value.stringVal), 2) + self.assertIn('foo', msg.meta[4].value.stringVal) + self.assertIn('bar', msg.meta[4].value.stringVal) + self.assertIn(42, msg.meta[4].value.intVal) class TestProtobufExtendedDNSErrorTags(DNSDistProtobufTest): _config_params = ['_testServerPort', '_protobufServerPort'] -- 2.47.3