From: Remi Gacogne Date: Tue, 18 Jan 2022 17:08:42 +0000 (+0100) Subject: dnsdist: Add Lua FFI bindings to look into the ring buffers X-Git-Tag: dnsdist-1.8.0-rc1~288^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9abc715beb0274e4fa0baefd571316e9e56fd993;p=thirdparty%2Fpdns.git dnsdist: Add Lua FFI bindings to look into the ring buffers --- diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h b/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h index 63172251b4..a22904a6b1 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h +++ b/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h @@ -163,3 +163,20 @@ void dnsdist_ffi_domain_list_free(dnsdist_ffi_domain_list_t*) __attribute__ ((vi size_t dnsdist_ffi_packetcache_get_domain_list_by_addr(const char* poolName, const char* addr, dnsdist_ffi_domain_list_t** out) __attribute__ ((visibility ("default"))); size_t dnsdist_ffi_packetcache_get_address_list_by_domain(const char* poolName, const char* domain, dnsdist_ffi_address_list_t** out) __attribute__ ((visibility ("default"))); + +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"))); +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"))); +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"))); +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"))); + +void dnsdist_ffi_ring_entry_list_free(dnsdist_ffi_ring_entry_list_t*) __attribute__ ((visibility ("default"))); + +size_t dnsdist_ffi_ring_get_entries(dnsdist_ffi_ring_entry_list_t** out) __attribute__ ((visibility ("default"))); +size_t dnsdist_ffi_ring_get_entries_by_addr(const char* addr, dnsdist_ffi_ring_entry_list_t** out) __attribute__ ((visibility ("default"))); +size_t dnsdist_ffi_ring_get_entries_by_mac(const char* addr, dnsdist_ffi_ring_entry_list_t** out) __attribute__ ((visibility ("default"))); diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi.cc b/pdns/dnsdistdist/dnsdist-lua-ffi.cc index a48c828473..38f01ce9f0 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/dnsdist-lua-ffi.cc @@ -864,3 +864,225 @@ size_t dnsdist_ffi_packetcache_get_address_list_by_domain(const char* poolName, } return count; } + +struct dnsdist_ffi_ring_entry_list_t +{ + struct entry + { + std::string qname; + std::string requestor; + std::string macAddr; + size_t size; + uint16_t qtype; + dnsdist::Protocol protocol; + bool isResponse; + }; + + std::vector d_entries; +}; + +bool dnsdist_ffi_ring_entry_is_response(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) +{ + if (list == nullptr || idx >= list->d_entries.size()) { + return false; + } + + return list->d_entries.at(idx).isResponse; +} + +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()) { + return nullptr; + } + + return list->d_entries.at(idx).qname.c_str(); +} + +uint16_t dnsdist_ffi_ring_entry_get_type(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).qtype; + +} + +const char* dnsdist_ffi_ring_entry_get_requestor(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).requestor.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()) { + return 0; + } + + //return static_cast(list->d_entries.at(idx).protocol); + #warning FIXME + return 0; +} + +uint16_t dnsdist_ffi_ring_entry_get_size(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).size; + +} + +bool dnsdist_ffi_ring_entry_has_mac_address(const dnsdist_ffi_ring_entry_list_t* list, size_t idx) +{ + if (list == nullptr || idx >= list->d_entries.size()) { + return false; + } + + return !list->d_entries.at(idx).macAddr.empty(); +} + +const char* dnsdist_ffi_ring_entry_get_mac_address(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).macAddr.data(); + +} + +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) +{ + 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.toString(), entry.hasmac ? std::string(reinterpret_cast(entry.macaddress.data()), entry.macaddress.size()) : std::string(), 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.toString(), std::string(), 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.toString(), 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) +{ + if (out == nullptr) { + return 0; + } + auto list = std::make_unique(); + + for (const auto& shard : g_rings.d_shards) { + { + auto ql = shard->queryRing.lock(); + for (const auto& entry : *ql) { + addRingEntryToList(list, entry); + } + } + { + auto rl = shard->respRing.lock(); + for (const auto& entry : *rl) { + addRingEntryToList(list, entry); + } + } + } + + auto count = list->d_entries.size(); + if (count > 0) { + *out = list.release(); + } + return count; +} + +size_t dnsdist_ffi_ring_get_entries_by_addr(const char* addr, dnsdist_ffi_ring_entry_list_t** out) +{ + if (out == nullptr || addr == nullptr) { + return 0; + } + ComboAddress ca; + try { + ca = ComboAddress(addr); + } + catch (const std::exception& e) { + vinfolog("Unable to convert address in dnsdist_ffi_ring_get_entries_by_addr: %s", e.what()); + return 0; + } + + auto list = std::make_unique(); + + auto compare = ComboAddress::addressOnlyEqual(); + for (const auto& shard : g_rings.d_shards) { + { + auto ql = shard->queryRing.lock(); + for (const auto& entry : *ql) { + if (!compare(entry.requestor, ca)) { + continue; + } + + addRingEntryToList(list, entry); + } + } + { + auto rl = shard->respRing.lock(); + for (const auto& entry : *rl) { + if (!compare(entry.requestor, ca)) { + continue; + } + + addRingEntryToList(list, entry); + } + } + } + + auto count = list->d_entries.size(); + if (count > 0) { + *out = list.release(); + } + return count; +} + +size_t dnsdist_ffi_ring_get_entries_by_mac(const char* addr, dnsdist_ffi_ring_entry_list_t** out) +{ + if (out == nullptr || addr == nullptr) { + return 0; + } + +#if !defined(DNSDIST_RINGS_WITH_MACADDRESS) + return 0; +#else + auto list = std::make_unique(); + + for (const auto& shard : g_rings.d_shards) { + auto ql = shard->queryRing.lock(); + for (const auto& entry : *ql) { + if (memcmp(addr, entry.macaddress.data(), entry.macaddress.size()) != 0) { + continue; + } + + addRingEntryToList(list, entry); + } + } + + auto count = list->d_entries.size(); + if (count > 0) { + *out = list.release(); + } + return count; +#endif +}