From: Remi Gacogne Date: Tue, 18 Jan 2022 17:08:42 +0000 (+0100) Subject: dnsdist: Add Lua FFI bindings to look into the cache X-Git-Tag: rec-4.9.0-alpha0~13^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bf55a81594c9c39a7773448adee6e062ce93a08c;p=thirdparty%2Fpdns.git dnsdist: Add Lua FFI bindings to look into the cache --- diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h b/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h index 15f4bb64b9..63172251b4 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h +++ b/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h @@ -151,3 +151,15 @@ typedef struct dnsdist_ffi_proxy_protocol_value { size_t dnsdist_ffi_generate_proxy_protocol_payload(size_t addrSize, const void* srcAddr, const void* dstAddr, uint16_t srcPort, uint16_t dstPort, bool tcp, size_t valuesCount, const dnsdist_ffi_proxy_protocol_value_t* values, void* out, size_t outSize) __attribute__ ((visibility ("default"))); size_t dnsdist_ffi_dnsquestion_generate_proxy_protocol_payload(const dnsdist_ffi_dnsquestion_t* dq, const size_t valuesCount, const dnsdist_ffi_proxy_protocol_value_t* values, void* out, const size_t outSize) __attribute__ ((visibility ("default"))); + +typedef struct dnsdist_ffi_domain_list_t dnsdist_ffi_domain_list_t; +typedef struct dnsdist_ffi_address_list_t dnsdist_ffi_address_list_t; + +const char* dnsdist_ffi_address_list_get(const dnsdist_ffi_address_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); +void dnsdist_ffi_address_list_free(dnsdist_ffi_address_list_t*) __attribute__ ((visibility ("default"))); + +const char* dnsdist_ffi_domain_list_get(const dnsdist_ffi_domain_list_t* list, size_t idx) __attribute__ ((visibility ("default"))); +void dnsdist_ffi_domain_list_free(dnsdist_ffi_domain_list_t*) __attribute__ ((visibility ("default"))); + +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"))); diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi.cc b/pdns/dnsdistdist/dnsdist-lua-ffi.cc index 4a61e942f7..4a69a2988a 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/dnsdist-lua-ffi.cc @@ -23,6 +23,7 @@ #include "dnsdist-lua-ffi.hh" #include "dnsdist-lua.hh" #include "dnsdist-ecs.hh" +#include "dnsdist-rings.hh" #include "dolog.hh" uint16_t dnsdist_ffi_dnsquestion_get_qtype(const dnsdist_ffi_dnsquestion_t* dq) @@ -715,3 +716,137 @@ size_t dnsdist_ffi_dnsquestion_generate_proxy_protocol_payload(const dnsdist_ffi return payload.size(); } + +struct dnsdist_ffi_domain_list_t +{ + std::vector d_domains; +}; +struct dnsdist_ffi_address_list_t { + std::vector d_addresses; +}; + +const char* dnsdist_ffi_domain_list_get(const dnsdist_ffi_domain_list_t* list, size_t idx) +{ + if (list == nullptr || idx >= list->d_domains.size()) { + return nullptr; + } + + return list->d_domains.at(idx).c_str(); +} + +void dnsdist_ffi_domain_list_free(dnsdist_ffi_domain_list_t* list) +{ + delete list; +} + +const char* dnsdist_ffi_address_list_get(const dnsdist_ffi_address_list_t* list, size_t idx) +{ + if (list == nullptr || idx >= list->d_addresses.size()) { + return nullptr; + } + + return list->d_addresses.at(idx).c_str(); +} + +void dnsdist_ffi_address_list_free(dnsdist_ffi_address_list_t* list) +{ + delete list; +} + +size_t dnsdist_ffi_packetcache_get_domain_list_by_addr(const char* poolName, const char* addr, dnsdist_ffi_domain_list_t** out) +{ + if (poolName == nullptr || addr == nullptr || out == nullptr) { + return 0; + } + + ComboAddress ca; + try { + ca = ComboAddress(addr); + } + catch (const std::exception& e) { + vinfolog("Error parsing address passed to dnsdist_ffi_packetcache_get_domain_list_by_addr: %s", e.what()); + return 0; + } + + const auto localPools = g_pools.getCopy(); + auto it = localPools.find(poolName); + if (it == localPools.end()) { + return 0; + } + + auto pool = it->second; + if (!pool->packetCache) { + return 0; + } + + auto domains = pool->packetCache->getDomainsContainingRecords(ca); + if (domains.size() == 0) { + return 0; + } + + auto list = std::make_unique(); + list->d_domains.reserve(domains.size()); + for (const auto& domain : domains) { + try { + list->d_domains.push_back(domain.toString()); + } + catch (const std::exception& e) { + vinfolog("Error converting domain to string in dnsdist_ffi_packetcache_get_domain_list_by_addr: %s", e.what()); + } + } + + size_t count = list->d_domains.size(); + if (count > 0) { + *out = list.release(); + } + return count; +} + +size_t dnsdist_ffi_packetcache_get_address_list_by_domain(const char* poolName, const char* domain, dnsdist_ffi_address_list_t** out) +{ + if (poolName == nullptr || domain == nullptr || out == nullptr) { + return 0; + } + + DNSName name; + try { + name = DNSName(domain); + } + catch (const std::exception& e) { + vinfolog("Error parsing domain passed to dnsdist_ffi_packetcache_get_address_list_by_domain: %s", e.what()); + return 0; + } + + const auto localPools = g_pools.getCopy(); + auto it = localPools.find(poolName); + if (it == localPools.end()) { + return 0; + } + + auto pool = it->second; + if (!pool->packetCache) { + return 0; + } + + auto addresses = pool->packetCache->getRecordsForDomain(name); + if (addresses.size() == 0) { + return 0; + } + + auto list = std::make_unique(); + list->d_addresses.reserve(addresses.size()); + for (const auto& addr : addresses) { + try { + list->d_addresses.push_back(addr.toString()); + } + catch (const std::exception& e) { + vinfolog("Error converting address to string in dnsdist_ffi_packetcache_get_address_list_by_domain: %s", e.what()); + } + } + + size_t count = list->d_addresses.size(); + if (count > 0) { + *out = list.release(); + } + return count; +}