]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Add the ability to insert Dynamic Blocks from Lua FFI
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 10 Nov 2023 15:17:49 +0000 (16:17 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 14 Nov 2023 14:43:36 +0000 (15:43 +0100)
pdns/dnsdistdist/dnsdist-lua-ffi-interface.h
pdns/dnsdistdist/dnsdist-lua-ffi.cc

index 622b3d90bf68a941b3387be1bcc7369dbbb1f515..face00a92055e7324bb0536dad6d8ec88990506c 100644 (file)
@@ -243,3 +243,12 @@ const char* dnsdist_ffi_network_message_get_payload(const dnsdist_ffi_network_me
 size_t dnsdist_ffi_network_message_get_payload_size(const dnsdist_ffi_network_message_t* msg) __attribute__ ((visibility ("default")));
 uint16_t dnsdist_ffi_network_message_get_endpoint_id(const dnsdist_ffi_network_message_t* msg) __attribute__ ((visibility ("default")));
 
+/* Add a dynamic block:
+   - address should be an IPv4 or IPv6 address, as a string (192.0.2.1). A port might be included (192.0.2.1:).
+   - reason is a description of why the block was inserted
+   - action should be a DNSAction
+   - duration is the duration of the block, in seconds
+   - clientIPMask indicates whether the exact IP address should be blocked (32 for IPv4, 128 for IPv6) or if a range should be used instead, by indicating the number of bits of the address to consider
+   - 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")));
index f7365bf7718b2c885072e767e93ac41091d39ea2..0f2a0ddf8792f1bdbffa7c18fb8e0ae493280f51 100644 (file)
@@ -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"
@@ -1696,3 +1697,41 @@ uint16_t dnsdist_ffi_network_message_get_endpoint_id(const dnsdist_ffi_network_m
   }
   return 0;
 }
+
+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("addDynamicBlock: Unable to parse '%s': %s", address, exp.what());
+      return false;
+    }
+    catch (const PDNSException& exp) {
+      errlog("addDynamicBlock: 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;
+}