diff options
Diffstat (limited to 'dnsdist-lua-ffi.cc')
-rw-r--r-- | dnsdist-lua-ffi.cc | 420 |
1 files changed, 379 insertions, 41 deletions
diff --git a/dnsdist-lua-ffi.cc b/dnsdist-lua-ffi.cc index bf46aad..6c08cfc 100644 --- a/dnsdist-lua-ffi.cc +++ b/dnsdist-lua-ffi.cc @@ -22,6 +22,7 @@ #include "dnsdist-async.hh" #include "dnsdist-dnsparser.hh" +#include "dnsdist-dynblocks.hh" #include "dnsdist-ecs.hh" #include "dnsdist-lua-ffi.hh" #include "dnsdist-mac-address.hh" @@ -67,6 +68,15 @@ void dnsdist_ffi_dnsquestion_get_localaddr(const dnsdist_ffi_dnsquestion_t* dq, dnsdist_ffi_comboaddress_to_raw(dq->dq->ids.origDest, addr, addrSize); } +bool dnsdist_ffi_dnsquestion_is_remote_v6(const dnsdist_ffi_dnsquestion_t* dnsQuestion) +{ + if (dnsQuestion == nullptr || dnsQuestion->dq == nullptr) { + return false; + } + + return dnsQuestion->dq->ids.origRemote.isIPv6(); +} + void dnsdist_ffi_dnsquestion_get_remoteaddr(const dnsdist_ffi_dnsquestion_t* dq, const void** addr, size_t* addrSize) { dnsdist_ffi_comboaddress_to_raw(dq->dq->ids.origRemote, addr, addrSize); @@ -129,7 +139,7 @@ int dnsdist_ffi_dnsquestion_get_rcode(const dnsdist_ffi_dnsquestion_t* dq) void* dnsdist_ffi_dnsquestion_get_header(const dnsdist_ffi_dnsquestion_t* dq) { - return dq->dq->getHeader(); + return dq->dq->getMutableHeader(); } uint16_t dnsdist_ffi_dnsquestion_get_len(const dnsdist_ffi_dnsquestion_t* dq) @@ -458,14 +468,30 @@ void dnsdist_ffi_dnsquestion_set_http_response(dnsdist_ffi_dnsquestion_t* dq, ui #ifdef HAVE_DNS_OVER_HTTPS PacketBuffer bodyVect(body, body + bodyLen); dq->dq->ids.du->setHTTPResponse(statusCode, std::move(bodyVect), contentType); - dq->dq->getHeader()->qr = true; + dnsdist::PacketMangling::editDNSHeaderFromPacket(dq->dq->getMutableData(), [](dnsheader& header) { + header.qr = true; + return true; + }); #endif } +void dnsdist_ffi_dnsquestion_set_extended_dns_error(dnsdist_ffi_dnsquestion_t* dnsQuestion, uint16_t infoCode, const char* extraText, size_t extraTextSize) +{ + EDNSExtendedError ede; + ede.infoCode = infoCode; + if (extraText != nullptr && extraTextSize > 0) { + ede.extraText = std::string(extraText, extraTextSize); + } + dnsQuestion->dq->ids.d_extendedError = std::make_unique<EDNSExtendedError>(ede); +} + void dnsdist_ffi_dnsquestion_set_rcode(dnsdist_ffi_dnsquestion_t* dq, int rcode) { - dq->dq->getHeader()->rcode = rcode; - dq->dq->getHeader()->qr = true; + dnsdist::PacketMangling::editDNSHeaderFromPacket(dq->dq->getMutableData(), [rcode](dnsheader& header) { + header.rcode = rcode; + header.qr = true; + return true; + }); } void dnsdist_ffi_dnsquestion_set_len(dnsdist_ffi_dnsquestion_t* dq, uint16_t len) @@ -571,8 +597,8 @@ void dnsdist_ffi_dnsquestion_send_trap(dnsdist_ffi_dnsquestion_t* dq, const char void dnsdist_ffi_dnsquestion_spoof_packet(dnsdist_ffi_dnsquestion_t* dq, const char* raw, size_t len) { std::string result; - SpoofAction sa(raw, len); - sa(dq->dq, &result); + SpoofAction tempSpoofAction(raw, len); + tempSpoofAction(dq->dq, &result); } void dnsdist_ffi_dnsquestion_spoof_raw(dnsdist_ffi_dnsquestion_t* dq, const dnsdist_ffi_raw_value_t* values, size_t valuesCount) @@ -585,8 +611,8 @@ void dnsdist_ffi_dnsquestion_spoof_raw(dnsdist_ffi_dnsquestion_t* dq, const dnsd } std::string result; - SpoofAction sa(data); - sa(dq->dq, &result); + SpoofAction tempSpoofAction(data, std::nullopt); + tempSpoofAction(dq->dq, &result); } void dnsdist_ffi_dnsquestion_spoof_addrs(dnsdist_ffi_dnsquestion_t* dq, const dnsdist_ffi_raw_value_t* values, size_t valuesCount) @@ -614,8 +640,8 @@ void dnsdist_ffi_dnsquestion_spoof_addrs(dnsdist_ffi_dnsquestion_t* dq, const dn } std::string result; - SpoofAction sa(data); - sa(dq->dq, &result); + SpoofAction tempSpoofAction(data); + tempSpoofAction(dq->dq, &result); } void dnsdist_ffi_dnsquestion_set_max_returned_ttl(dnsdist_ffi_dnsquestion_t* dq, uint32_t max) @@ -749,7 +775,7 @@ bool dnsdist_ffi_dnsresponse_rebase(dnsdist_ffi_dnsresponse_t* dr, const char* i } // set qname to new one - dr->dr->ids.qname = parsed; + dr->dr->ids.qname = std::move(parsed); dr->dr->ids.skipCache = true; } catch (const std::exception& e) { @@ -929,7 +955,8 @@ bool dnsdist_ffi_drop_from_async(uint16_t asyncID, uint16_t queryID) struct timeval now; gettimeofday(&now, nullptr); - sender->notifyIOError(std::move(query->query.d_idstate), now); + TCPResponse tresponse(std::move(query->query)); + sender->notifyIOError(now, std::move(tresponse)); return true; } @@ -949,11 +976,15 @@ bool dnsdist_ffi_set_answer_from_async(uint16_t asyncID, uint16_t queryID, const return false; } - auto oldId = reinterpret_cast<const dnsheader*>(query->query.d_buffer.data())->id; + dnsheader_aligned alignedHeader(query->query.d_buffer.data()); + auto oldID = alignedHeader->id; query->query.d_buffer.clear(); query->query.d_buffer.insert(query->query.d_buffer.begin(), raw, raw + rawSize); - reinterpret_cast<dnsheader*>(query->query.d_buffer.data())->id = oldId; + dnsdist::PacketMangling::editDNSHeaderFromPacket(query->query.d_buffer, [oldID](dnsheader& header) { + header.id = oldID; + return true; + }); query->query.d_idstate.skipCache = true; return dnsdist::queueQueryResumptionEvent(std::move(query)); @@ -978,7 +1009,7 @@ const char* getLuaFFIWrappers() void setupLuaLoadBalancingContext(LuaContext& luaCtx) { - setupLuaBindings(luaCtx, true); + setupLuaBindings(luaCtx, true, false); setupLuaBindingsDNSQuestion(luaCtx); setupLuaBindingsKVS(luaCtx, true); setupLuaVars(luaCtx); @@ -1202,7 +1233,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; @@ -1220,6 +1255,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()) { @@ -1236,7 +1280,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) @@ -1248,6 +1291,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()) { @@ -1264,7 +1316,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 false; + } + + return list->d_entries.at(idx).dh.aa == 1; +} + +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 false; + } + + return list->d_entries.at(idx).dh.rd == 1; +} + +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 false; + } + + return list->d_entries.at(idx).dh.tc == 1; +} + +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) @@ -1283,7 +1415,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) @@ -1291,22 +1422,23 @@ void dnsdist_ffi_ring_entry_list_free(dnsdist_ffi_ring_entry_list_t* list) delete list; } -template<typename T> static void addRingEntryToList(std::unique_ptr<dnsdist_ffi_ring_entry_list_t>& list, const T& entry) +template<typename T> static void addRingEntryToList(std::unique_ptr<dnsdist_ffi_ring_entry_list_t>& list, const struct timespec& now, const T& entry) { + auto age = DiffTime(entry.when, now); + constexpr bool response = std::is_same_v<T, Rings::Response>; -#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<const char*>(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<const char*>(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.toString(), 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.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) @@ -1315,18 +1447,22 @@ size_t dnsdist_ffi_ring_get_entries(dnsdist_ffi_ring_entry_list_t** out) return 0; } auto list = std::make_unique<dnsdist_ffi_ring_entry_list_t>(); + 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); } } } @@ -1357,6 +1493,10 @@ size_t dnsdist_ffi_ring_get_entries_by_addr(const char* addr, dnsdist_ffi_ring_e } auto list = std::make_unique<dnsdist_ffi_ring_entry_list_t>(); + struct timespec now + { + }; + gettime(&now); auto compare = ComboAddress::addressOnlyEqual(); for (const auto& shard : g_rings.d_shards) { @@ -1367,7 +1507,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); } } { @@ -1377,7 +1517,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,6 +1539,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<dnsdist_ffi_ring_entry_list_t>(); + struct timespec now + { + }; + gettime(&now); for (const auto& shard : g_rings.d_shards) { auto ql = shard->queryRing.lock(); @@ -1407,7 +1551,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); } } @@ -1607,17 +1751,14 @@ bool dnsdist_ffi_metric_declare(const char* name, size_t nameLen, const char* ty if (name == nullptr || nameLen == 0 || type == nullptr || description == nullptr) { return false; } - auto result = dnsdist::metrics::declareCustomMetric(name, type, description, customName ? std::optional<std::string>(customName) : std::nullopt); - if (result) { - return false; - } - return true; + auto result = dnsdist::metrics::declareCustomMetric(name, type, description, customName != nullptr ? std::optional<std::string>(customName) : std::nullopt); + return !result; } void dnsdist_ffi_metric_inc(const char* metricName, size_t metricNameLen) { auto result = dnsdist::metrics::incrementCustomCounter(std::string_view(metricName, metricNameLen), 1U); - if (const auto* errorStr = std::get_if<dnsdist::metrics::Error>(&result)) { + if (std::get_if<dnsdist::metrics::Error>(&result) != nullptr) { return; } } @@ -1625,7 +1766,7 @@ void dnsdist_ffi_metric_inc(const char* metricName, size_t metricNameLen) void dnsdist_ffi_metric_inc_by(const char* metricName, size_t metricNameLen, uint64_t value) { auto result = dnsdist::metrics::incrementCustomCounter(std::string_view(metricName, metricNameLen), value); - if (const auto* errorStr = std::get_if<dnsdist::metrics::Error>(&result)) { + if (std::get_if<dnsdist::metrics::Error>(&result) != nullptr) { return; } } @@ -1633,7 +1774,7 @@ void dnsdist_ffi_metric_inc_by(const char* metricName, size_t metricNameLen, uin void dnsdist_ffi_metric_dec(const char* metricName, size_t metricNameLen) { auto result = dnsdist::metrics::decrementCustomCounter(std::string_view(metricName, metricNameLen), 1U); - if (const auto* errorStr = std::get_if<dnsdist::metrics::Error>(&result)) { + if (std::get_if<dnsdist::metrics::Error>(&result) != nullptr) { return; } } @@ -1641,7 +1782,7 @@ void dnsdist_ffi_metric_dec(const char* metricName, size_t metricNameLen) void dnsdist_ffi_metric_set(const char* metricName, size_t metricNameLen, double value) { auto result = dnsdist::metrics::setCustomGauge(std::string_view(metricName, metricNameLen), value); - if (const auto* errorStr = std::get_if<dnsdist::metrics::Error>(&result)) { + if (std::get_if<dnsdist::metrics::Error>(&result) != nullptr) { return; } } @@ -1649,7 +1790,7 @@ void dnsdist_ffi_metric_set(const char* metricName, size_t metricNameLen, double double dnsdist_ffi_metric_get(const char* metricName, size_t metricNameLen, bool isCounter) { auto result = dnsdist::metrics::getCustomMetric(std::string_view(metricName, metricNameLen)); - if (const auto* errorStr = std::get_if<dnsdist::metrics::Error>(&result)) { + if (std::get_if<dnsdist::metrics::Error>(&result) != nullptr) { return 0.; } return std::get<double>(result); @@ -1678,3 +1819,200 @@ uint16_t dnsdist_ffi_network_message_get_endpoint_id(const dnsdist_ffi_network_m } return 0; } + +#ifndef DISABLE_DYNBLOCKS +bool dnsdist_ffi_dynamic_blocks_add(const char* address, const char* message, uint8_t action, unsigned int duration, uint8_t clientIPMask, uint8_t clientIPPortMask) +{ + try { + ComboAddress clientIPCA; + try { + clientIPCA = ComboAddress(address); + } + catch (const std::exception& exp) { + errlog("dnsdist_ffi_dynamic_blocks_add: Unable to parse '%s': %s", address, exp.what()); + return false; + } + catch (const PDNSException& exp) { + errlog("dnsdist_ffi_dynamic_blocks_add: Unable to parse '%s': %s", address, exp.reason); + return false; + } + + AddressAndPortRange target(clientIPCA, clientIPMask, clientIPPortMask); + + struct timespec now + { + }; + gettime(&now); + auto slow = g_dynblockNMG.getCopy(); + if (dnsdist::DynamicBlocks::addOrRefreshBlock(slow, now, target, message, duration, static_cast<DNSAction::Action>(action), false, false)) { + g_dynblockNMG.setState(slow); + return true; + } + } + catch (const std::exception& exp) { + errlog("Exception in dnsdist_ffi_dynamic_blocks_add: %s", exp.what()); + } + catch (const PDNSException& exp) { + errlog("Exception in dnsdist_ffi_dynamic_blocks_add: %s", exp.reason); + } + catch (...) { + errlog("Exception in dnsdist_ffi_dynamic_blocks_add"); + } + return false; +} + +bool dnsdist_ffi_dynamic_blocks_smt_add(const char* suffix, const char* message, uint8_t action, unsigned int duration) +{ + try { + DNSName domain; + try { + domain = DNSName(suffix); + domain.makeUsLowerCase(); + } + catch (const std::exception& exp) { + errlog("dnsdist_ffi_dynamic_blocks_smt_add: Unable to parse '%s': %s", suffix, exp.what()); + return false; + } + catch (const PDNSException& exp) { + errlog("dnsdist_ffi_dynamic_blocks_smt_add: Unable to parse '%s': %s", suffix, exp.reason); + return false; + } + + struct timespec now + { + }; + gettime(&now); + auto slow = g_dynblockSMT.getCopy(); + if (dnsdist::DynamicBlocks::addOrRefreshBlockSMT(slow, now, domain, message, duration, static_cast<DNSAction::Action>(action), false)) { + g_dynblockSMT.setState(slow); + return true; + } + } + catch (const std::exception& exp) { + errlog("Exception in dnsdist_ffi_dynamic_blocks_smt_add: %s", exp.what()); + } + catch (const PDNSException& exp) { + errlog("Exception in dnsdist_ffi_dynamic_blocks_smt_add: %s", exp.reason); + } + catch (...) { + errlog("Exception in dnsdist_ffi_dynamic_blocks_smt_add"); + } + return false; +} + +struct dnsdist_ffi_dynamic_blocks_list_t +{ + std::vector<dnsdist_ffi_dynamic_block_entry_t> d_entries; +}; + +size_t dnsdist_ffi_dynamic_blocks_get_entries(dnsdist_ffi_dynamic_blocks_list_t** out) +{ + if (out == nullptr) { + return 0; + } + + auto list = std::make_unique<dnsdist_ffi_dynamic_blocks_list_t>(); + + struct timespec now + { + }; + gettime(&now); + + auto fullCopy = g_dynblockNMG.getCopy(); + for (const auto& entry : fullCopy) { + const auto& client = entry.first; + const auto& details = entry.second; + if (!(now < details.until)) { + continue; + } + + uint64_t counter = details.blocks; + if (g_defaultBPFFilter && details.bpf) { + counter += g_defaultBPFFilter->getHits(client.getNetwork()); + } + list->d_entries.push_back({strdup(client.toString().c_str()), strdup(details.reason.c_str()), counter, static_cast<uint64_t>(details.until.tv_sec - now.tv_sec), static_cast<uint8_t>(details.action != DNSAction::Action::None ? details.action : g_dynBlockAction), g_defaultBPFFilter && details.bpf, details.warning}); + } + + auto count = list->d_entries.size(); + *out = list.release(); + return count; +} + +size_t dnsdist_ffi_dynamic_blocks_smt_get_entries(dnsdist_ffi_dynamic_blocks_list_t** out) +{ + if (out == nullptr) { + return 0; + } + + auto list = std::make_unique<dnsdist_ffi_dynamic_blocks_list_t>(); + + struct timespec now + { + }; + gettime(&now); + + auto fullCopy = g_dynblockSMT.getCopy(); + fullCopy.visit([&now, &list](const SuffixMatchTree<DynBlock>& node) { + if (!(now < node.d_value.until)) { + return; + } + auto entry = node.d_value; + string key("empty"); + if (!entry.domain.empty()) { + key = entry.domain.toString(); + } + if (entry.action == DNSAction::Action::None) { + entry.action = g_dynBlockAction; + } + list->d_entries.push_back({strdup(key.c_str()), strdup(entry.reason.c_str()), entry.blocks, static_cast<uint64_t>(entry.until.tv_sec - now.tv_sec), static_cast<uint8_t>(entry.action), entry.bpf, entry.warning}); + }); + + auto count = list->d_entries.size(); + *out = list.release(); + return count; +} + +const dnsdist_ffi_dynamic_block_entry_t* dnsdist_ffi_dynamic_blocks_list_get(const dnsdist_ffi_dynamic_blocks_list_t* list, size_t idx) +{ + if (list == nullptr) { + return nullptr; + } + + if (idx >= list->d_entries.size()) { + return nullptr; + } + + return &list->d_entries.at(idx); +} + +void dnsdist_ffi_dynamic_blocks_list_free(dnsdist_ffi_dynamic_blocks_list_t* list) +{ + if (list == nullptr) { + return; + } + + for (auto& entry : list->d_entries) { + // NOLINTNEXTLINE(cppcoreguidelines-owning-memory,cppcoreguidelines-no-malloc): this is a C API, RAII is not an option + free(entry.key); + // NOLINTNEXTLINE(cppcoreguidelines-owning-memory,cppcoreguidelines-no-malloc): this is a C API, RAII is not an option + free(entry.reason); + } + + // NOLINTNEXTLINE(cppcoreguidelines-owning-memory): this is a C API, RAII is not an option + delete list; +} + +#endif /* DISABLE_DYNBLOCKS */ + +uint32_t dnsdist_ffi_hash(uint32_t seed, const unsigned char* data, size_t dataSize, bool caseInsensitive) +{ + if (data == nullptr || dataSize == 0) { + return seed; + } + + if (caseInsensitive) { + return burtleCI(data, dataSize, seed); + } + + return burtle(data, dataSize, seed); +} |