- clientIPPort indicates It is also possible to take the IPv4 UDP and TCP ports into account, for CGNAT deployments, by setting the number of bits of the port to consider. For example passing 2 as the last parameter, which only makes sense if the previous parameters are respectively 32 and 128, will split a given IP address into four port ranges: 0-16383, 16384-32767, 32768-49151 and 49152-65535.
*/
bool dnsdist_ffi_dynamic_blocks_add(const char* address, const char* message, uint8_t action, unsigned int duration, uint8_t clientIPMask, uint8_t clientIPPortMask) __attribute__ ((visibility ("default")));
+bool dnsdist_ffi_dynamic_blocks_smt_add(const char* suffix, const char* message, uint8_t action, unsigned int duration) __attribute__ ((visibility ("default")));
typedef struct dnsdist_ffi_dynamic_block_entry {
- char* client;
+ char* key; /* Client IP for NMT blocks, domain name for SMT ones */
char* reason;
uint64_t blockedQueries;
uint64_t remainingTime;
typedef struct dnsdist_ffi_dynamic_blocks_list_t dnsdist_ffi_dynamic_blocks_list_t;
size_t dnsdist_ffi_dynamic_blocks_get_entries(dnsdist_ffi_dynamic_blocks_list_t** out) __attribute__ ((visibility ("default")));
+size_t dnsdist_ffi_dynamic_blocks_smt_get_entries(dnsdist_ffi_dynamic_blocks_list_t** out) __attribute__ ((visibility ("default")));
const dnsdist_ffi_dynamic_block_entry_t* dnsdist_ffi_dynamic_blocks_list_get(const dnsdist_ffi_dynamic_blocks_list_t* list, size_t idx) __attribute__ ((visibility ("default")));
void dnsdist_ffi_dynamic_blocks_list_free(dnsdist_ffi_dynamic_blocks_list_t*) __attribute__ ((visibility ("default")));
clientIPCA = ComboAddress(address);
}
catch (const std::exception& exp) {
- errlog("addDynamicBlock: Unable to parse '%s': %s", address, exp.what());
+ errlog("dnsdist_ffi_dynamic_blocks_add: Unable to parse '%s': %s", address, exp.what());
return false;
}
catch (const PDNSException& exp) {
- errlog("addDynamicBlock: Unable to parse '%s': %s", address, exp.reason);
+ errlog("dnsdist_ffi_dynamic_blocks_add: Unable to parse '%s': %s", address, exp.reason);
return false;
}
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;
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) {
}
for (auto& entry : list->d_entries) {
- free(entry.client);
+ free(entry.key);
free(entry.reason);
}