From: Remi Gacogne Date: Tue, 14 Nov 2023 12:22:22 +0000 (+0100) Subject: dnsdist: Add more Lua FFI bindings for the ring entries X-Git-Tag: rec-5.0.0-rc1~31^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7c5c61f33d5a1742090119a145aa71ce1b36a20c;p=thirdparty%2Fpdns.git dnsdist: Add more Lua FFI bindings for the ring entries --- diff --git a/pdns/dnsdist-rings.hh b/pdns/dnsdist-rings.hh index 6bd93afb7d..755d769797 100644 --- a/pdns/dnsdist-rings.hh +++ b/pdns/dnsdist-rings.hh @@ -58,7 +58,7 @@ struct Rings { struct timespec when; struct dnsheader dh; unsigned int usec; - unsigned int size; + uint16_t size; uint16_t qtype; // outgoing protocol dnsdist::Protocol protocol; @@ -236,7 +236,7 @@ private: #endif } - void insertResponseLocked(boost::circular_buffer& ring, const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, unsigned int usec, unsigned int size, const struct dnsheader& dh, const ComboAddress& backend, dnsdist::Protocol protocol) + void insertResponseLocked(boost::circular_buffer& ring, const struct timespec& when, const ComboAddress& requestor, const DNSName& name, uint16_t qtype, unsigned int usec, uint16_t size, const struct dnsheader& dh, const ComboAddress& backend, dnsdist::Protocol protocol) { if (!ring.full()) { d_nbResponseEntries++; diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h b/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h index a0ff3bf9fb..e0c980e49e 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h +++ b/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h @@ -193,11 +193,22 @@ size_t dnsdist_ffi_packetcache_get_address_list_by_domain(const char* poolName, typedef struct dnsdist_ffi_ring_entry_list_t dnsdist_ffi_ring_entry_list_t; bool dnsdist_ffi_ring_entry_is_response(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); +double dnsdist_ffi_ring_entry_get_age(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); const char* dnsdist_ffi_ring_entry_get_name(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); uint16_t dnsdist_ffi_ring_entry_get_type(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); const char* dnsdist_ffi_ring_entry_get_requestor(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); +const char* dnsdist_ffi_ring_entry_get_backend(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); uint8_t dnsdist_ffi_ring_entry_get_protocol(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); uint16_t dnsdist_ffi_ring_entry_get_size(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); +uint16_t dnsdist_ffi_ring_entry_get_latency(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); +uint16_t dnsdist_ffi_ring_entry_get_id(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); +uint8_t dnsdist_ffi_ring_entry_get_rcode(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); +bool dnsdist_ffi_ring_entry_get_aa(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); +bool dnsdist_ffi_ring_entry_get_rd(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); +bool dnsdist_ffi_ring_entry_get_tc(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); +uint16_t dnsdist_ffi_ring_entry_get_ancount(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); +uint16_t dnsdist_ffi_ring_entry_get_nscount(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); +uint16_t dnsdist_ffi_ring_entry_get_arcount(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); bool dnsdist_ffi_ring_entry_has_mac_address(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); const char* dnsdist_ffi_ring_entry_get_mac_address(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi.cc b/pdns/dnsdistdist/dnsdist-lua-ffi.cc index 1ec5c03782..7d1d831d17 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/dnsdist-lua-ffi.cc @@ -1224,7 +1224,11 @@ struct dnsdist_ffi_ring_entry_list_t std::string qname; std::string requestor; std::string macAddr; - size_t size; + std::string ds; + dnsheader dh; + double age; + unsigned int latency; + uint16_t size; uint16_t qtype; dnsdist::Protocol protocol; bool isResponse; @@ -1242,6 +1246,15 @@ bool dnsdist_ffi_ring_entry_is_response(const dnsdist_ffi_ring_entry_list_t* lis return list->d_entries.at(idx).isResponse; } +double dnsdist_ffi_ring_entry_get_age(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) +{ + if (list == nullptr || idx >= list->d_entries.size()) { + return 0; + } + + return list->d_entries.at(idx).age; +} + const char* dnsdist_ffi_ring_entry_get_name(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) { if (list == nullptr || idx >= list->d_entries.size()) { @@ -1258,7 +1271,6 @@ uint16_t dnsdist_ffi_ring_entry_get_type(const dnsdist_ffi_ring_entry_list_t* li } return list->d_entries.at(idx).qtype; - } const char* dnsdist_ffi_ring_entry_get_requestor(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) @@ -1270,6 +1282,15 @@ const char* dnsdist_ffi_ring_entry_get_requestor(const dnsdist_ffi_ring_entry_li return list->d_entries.at(idx).requestor.c_str(); } +const char* dnsdist_ffi_ring_entry_get_backend(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) +{ + if (list == nullptr || idx >= list->d_entries.size()) { + return nullptr; + } + + return list->d_entries.at(idx).ds.c_str(); +} + uint8_t dnsdist_ffi_ring_entry_get_protocol(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) { if (list == nullptr || idx >= list->d_entries.size()) { @@ -1286,7 +1307,87 @@ uint16_t dnsdist_ffi_ring_entry_get_size(const dnsdist_ffi_ring_entry_list_t* li } return list->d_entries.at(idx).size; +} + +uint16_t dnsdist_ffi_ring_entry_get_latency(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) +{ + if (list == nullptr || idx >= list->d_entries.size()) { + return 0; + } + + return list->d_entries.at(idx).latency; +} + +uint16_t dnsdist_ffi_ring_entry_get_id(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) +{ + if (list == nullptr || idx >= list->d_entries.size()) { + return 0; + } + + return ntohs(list->d_entries.at(idx).dh.id); +} + +uint8_t dnsdist_ffi_ring_entry_get_rcode(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) +{ + if (list == nullptr || idx >= list->d_entries.size()) { + return 0; + } + + return list->d_entries.at(idx).dh.rcode; +} + +bool dnsdist_ffi_ring_entry_get_aa(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) +{ + if (list == nullptr || idx >= list->d_entries.size()) { + return 0; + } + + return list->d_entries.at(idx).dh.aa; +} + +bool dnsdist_ffi_ring_entry_get_rd(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) +{ + if (list == nullptr || idx >= list->d_entries.size()) { + return 0; + } + return list->d_entries.at(idx).dh.rd; +} + +bool dnsdist_ffi_ring_entry_get_tc(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) +{ + if (list == nullptr || idx >= list->d_entries.size()) { + return 0; + } + + return list->d_entries.at(idx).dh.tc; +} + +uint16_t dnsdist_ffi_ring_entry_get_ancount(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) +{ + if (list == nullptr || idx >= list->d_entries.size()) { + return 0; + } + + return ntohs(list->d_entries.at(idx).dh.ancount); +} + +uint16_t dnsdist_ffi_ring_entry_get_nscount(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) +{ + if (list == nullptr || idx >= list->d_entries.size()) { + return 0; + } + + return ntohs(list->d_entries.at(idx).dh.nscount); +} + +uint16_t dnsdist_ffi_ring_entry_get_arcount(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) +{ + if (list == nullptr || idx >= list->d_entries.size()) { + return 0; + } + + return ntohs(list->d_entries.at(idx).dh.arcount); } bool dnsdist_ffi_ring_entry_has_mac_address(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) @@ -1305,7 +1406,6 @@ const char* dnsdist_ffi_ring_entry_get_mac_address(const dnsdist_ffi_ring_entry_ } return list->d_entries.at(idx).macAddr.data(); - } void dnsdist_ffi_ring_entry_list_free(dnsdist_ffi_ring_entry_list_t* list) @@ -1313,22 +1413,23 @@ void dnsdist_ffi_ring_entry_list_free(dnsdist_ffi_ring_entry_list_t* list) delete list; } -template static void addRingEntryToList(std::unique_ptr& list, const T& entry) +template static void addRingEntryToList(std::unique_ptr& list, const struct timespec& now, const T& entry) { + auto age = DiffTime(entry.when, now); + constexpr bool response = std::is_same_v; -#if defined(DNSDIST_RINGS_WITH_MACADDRESS) if constexpr (!response) { - dnsdist_ffi_ring_entry_list_t::entry tmp{entry.name.toString(), entry.requestor.toStringWithPort(), entry.hasmac ? std::string(reinterpret_cast(entry.macaddress.data()), entry.macaddress.size()) : std::string(), entry.size, entry.qtype, entry.protocol, response}; +#if defined(DNSDIST_RINGS_WITH_MACADDRESS) + dnsdist_ffi_ring_entry_list_t::entry tmp{entry.name.toString(), entry.requestor.toStringWithPort(), entry.hasmac ? std::string(reinterpret_cast(entry.macaddress.data()), entry.macaddress.size()) : std::string(), std::string(), entry.dh, age, 0, entry.size, entry.qtype, entry.protocol, response}; +#else + dnsdist_ffi_ring_entry_list_t::entry tmp{entry.name.toString(), entry.requestor.toStringWithPort(), std::string(), std::string(), entry.dh, age, 0, entry.size, entry.qtype, entry.protocol, response}; +#endif list->d_entries.push_back(std::move(tmp)); } else { - dnsdist_ffi_ring_entry_list_t::entry tmp{entry.name.toString(), entry.requestor.toStringWithPort(), std::string(), entry.size, entry.qtype, entry.protocol, response}; + dnsdist_ffi_ring_entry_list_t::entry tmp{entry.name.toString(), entry.requestor.toStringWithPort(), std::string(), entry.ds.toStringWithPort(), entry.dh, age, entry.usec, entry.size, entry.qtype, entry.protocol, response}; list->d_entries.push_back(std::move(tmp)); } -#else - dnsdist_ffi_ring_entry_list_t::entry tmp{entry.name.toString(), entry.requestor.toStringWithPort(), std::string(), entry.size, entry.qtype, entry.protocol, response}; - list->d_entries.push_back(std::move(tmp)); -#endif } size_t dnsdist_ffi_ring_get_entries(dnsdist_ffi_ring_entry_list_t** out) @@ -1337,18 +1438,22 @@ size_t dnsdist_ffi_ring_get_entries(dnsdist_ffi_ring_entry_list_t** out) return 0; } auto list = std::make_unique(); + struct timespec now + { + }; + gettime(&now); for (const auto& shard : g_rings.d_shards) { { auto ql = shard->queryRing.lock(); for (const auto& entry : *ql) { - addRingEntryToList(list, entry); + addRingEntryToList(list, now, entry); } } { auto rl = shard->respRing.lock(); for (const auto& entry : *rl) { - addRingEntryToList(list, entry); + addRingEntryToList(list, now, entry); } } } @@ -1379,6 +1484,10 @@ size_t dnsdist_ffi_ring_get_entries_by_addr(const char* addr, dnsdist_ffi_ring_e } auto list = std::make_unique(); + struct timespec now + { + }; + gettime(&now); auto compare = ComboAddress::addressOnlyEqual(); for (const auto& shard : g_rings.d_shards) { @@ -1389,7 +1498,7 @@ size_t dnsdist_ffi_ring_get_entries_by_addr(const char* addr, dnsdist_ffi_ring_e continue; } - addRingEntryToList(list, entry); + addRingEntryToList(list, now, entry); } } { @@ -1399,7 +1508,7 @@ size_t dnsdist_ffi_ring_get_entries_by_addr(const char* addr, dnsdist_ffi_ring_e continue; } - addRingEntryToList(list, entry); + addRingEntryToList(list, now, entry); } } } @@ -1421,6 +1530,10 @@ size_t dnsdist_ffi_ring_get_entries_by_mac(const char* addr, dnsdist_ffi_ring_en return 0; #else auto list = std::make_unique(); + struct timespec now + { + }; + gettime(&now); for (const auto& shard : g_rings.d_shards) { auto ql = shard->queryRing.lock(); @@ -1429,7 +1542,7 @@ size_t dnsdist_ffi_ring_get_entries_by_mac(const char* addr, dnsdist_ffi_ring_en continue; } - addRingEntryToList(list, entry); + addRingEntryToList(list, now, entry); } } diff --git a/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc b/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc index 56047a7f0c..72b3d38308 100644 --- a/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc @@ -684,6 +684,12 @@ BOOST_AUTO_TEST_CASE(test_RingBuffers) { dnsheader dh; memset(&dh, 0, sizeof(dh)); + dh.id = htons(42); + dh.rd = 1; + dh.ancount = htons(1); + dh.nscount = htons(1); + dh.arcount = htons(1); + dh.rcode = RCode::NXDomain; DNSName qname("rings.luaffi.powerdns.com."); ComboAddress requestor1("192.0.2.1"); ComboAddress backend("192.0.2.42"); @@ -716,11 +722,22 @@ BOOST_AUTO_TEST_CASE(test_RingBuffers) BOOST_CHECK_EQUAL(dnsdist_ffi_ring_get_entries_by_mac(nullptr, nullptr), 0U); BOOST_CHECK(list == nullptr); BOOST_CHECK(!dnsdist_ffi_ring_entry_is_response(nullptr, 0)); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_age(nullptr, 0) == 0.0); BOOST_CHECK(dnsdist_ffi_ring_entry_get_name(nullptr, 0) == nullptr); BOOST_CHECK(dnsdist_ffi_ring_entry_get_type(nullptr, 0) == 0); BOOST_CHECK(dnsdist_ffi_ring_entry_get_requestor(nullptr, 0) == nullptr); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_backend(nullptr, 0) == nullptr); BOOST_CHECK(dnsdist_ffi_ring_entry_get_protocol(nullptr, 0) == 0); BOOST_CHECK(dnsdist_ffi_ring_entry_get_size(nullptr, 0) == 0); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_latency(nullptr, 0) == 0); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_id(nullptr, 0) == 0); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_rcode(nullptr, 0) == 0); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_aa(nullptr, 0) == false); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_rd(nullptr, 0) == false); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_tc(nullptr, 0) == false); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_ancount(nullptr, 0) == 0); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_nscount(nullptr, 0) == 0); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_arcount(nullptr, 0) == 0); BOOST_CHECK(!dnsdist_ffi_ring_entry_has_mac_address(nullptr, 0)); BOOST_CHECK(dnsdist_ffi_ring_entry_get_mac_address(nullptr, 0) == nullptr); } @@ -732,11 +749,25 @@ BOOST_AUTO_TEST_CASE(test_RingBuffers) BOOST_CHECK(dnsdist_ffi_ring_entry_is_response(list, 1)); for (size_t idx = 0; idx < 2; idx++) { + BOOST_CHECK(dnsdist_ffi_ring_entry_get_age(list, idx) >= 0.0); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_age(list, idx) < 2.0); BOOST_CHECK(dnsdist_ffi_ring_entry_get_name(list, idx) == qname.toString()); BOOST_CHECK(dnsdist_ffi_ring_entry_get_type(list, idx) == qtype); BOOST_CHECK(dnsdist_ffi_ring_entry_get_requestor(list, idx) == requestor1.toStringWithPort()); BOOST_CHECK(dnsdist_ffi_ring_entry_get_protocol(list, idx) == protocol.toNumber()); BOOST_CHECK_EQUAL(dnsdist_ffi_ring_entry_get_size(list, idx), size); + BOOST_CHECK_EQUAL(dnsdist_ffi_ring_entry_get_id(list, idx), 42U); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_aa(list, idx) == false); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_rd(list, idx) == true); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_tc(list, idx) == false); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_ancount(list, idx) == 1); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_nscount(list, idx) == 1); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_arcount(list, idx) == 1); + BOOST_CHECK(dnsdist_ffi_ring_entry_get_rcode(list, idx) == RCode::NXDomain); + if (dnsdist_ffi_ring_entry_is_response(list, idx)) { + BOOST_CHECK(dnsdist_ffi_ring_entry_get_backend(list, idx) == backend.toStringWithPort()); + BOOST_CHECK_EQUAL(dnsdist_ffi_ring_entry_get_latency(list, idx), responseTime); + } BOOST_CHECK(!dnsdist_ffi_ring_entry_has_mac_address(list, idx)); BOOST_CHECK(dnsdist_ffi_ring_entry_get_mac_address(list, idx) == std::string()); } @@ -744,7 +775,7 @@ BOOST_AUTO_TEST_CASE(test_RingBuffers) dnsdist_ffi_ring_entry_list_free(list); list = nullptr; - // no the right requestor + // not the right requestor BOOST_REQUIRE_EQUAL(dnsdist_ffi_ring_get_entries_by_addr("192.0.2.2", &list), 0U); BOOST_CHECK(list == nullptr);