]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Generate C++ factory and Lua bindings code from YAML definitions
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 24 Dec 2024 15:17:37 +0000 (16:17 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 16 Jan 2025 08:50:28 +0000 (09:50 +0100)
pdns/dnsdistdist/Makefile.am
pdns/dnsdistdist/dnsdist-actions-factory-generated.cc [new file with mode: 0644]
pdns/dnsdistdist/dnsdist-actions-factory-generated.hh [new file with mode: 0644]
pdns/dnsdistdist/dnsdist-lua-actions-generated.cc [new file with mode: 0644]
pdns/dnsdistdist/dnsdist-lua-response-actions-generated.cc [new file with mode: 0644]
pdns/dnsdistdist/dnsdist-lua-selectors-generated.cc [new file with mode: 0644]
pdns/dnsdistdist/dnsdist-response-actions-factory-generated.cc [new file with mode: 0644]
pdns/dnsdistdist/dnsdist-response-actions-factory-generated.hh [new file with mode: 0644]
pdns/dnsdistdist/dnsdist-rules-generator.py [new file with mode: 0644]
pdns/dnsdistdist/dnsdist-selectors-factory-generated.cc [new file with mode: 0644]
pdns/dnsdistdist/dnsdist-selectors-factory-generated.hh [new file with mode: 0644]

index cefe0b021ded7445d9ea177ceedb631a9dafb661..f7ca43fab08968afbe753e76250013c70b843d1a 100644 (file)
@@ -35,7 +35,13 @@ dnslabeltext.cc: dnslabeltext.rl
        $(AM_V_GEN)$(RAGEL) $< -o dnslabeltext.cc
 
 BUILT_SOURCES=htmlfiles.h \
+       dnsdist-actions-factory-generated.cc dnsdist-actions-factory-generated.hh \
        dnsdist-lua-ffi-interface.inc \
+       dnsdist-lua-actions-generated.cc dnsdist-lua-response-actions-generated.cc \
+       dnsdist-response-actions-factory-generated.cc dnsdist-response-actions-factory-generated.hh \
+       dnsdist-rust-bridge-actions-generated.cc dnsdist-rust-bridge-actions-generated.hh \
+       dnsdist-rust-bridge-selectors-generated.cc dnsdist-rust-bridge-selectors-generated.hh \
+       dnsdist-selectors-factory-generated.cc dnsdist-selectors-factory-generated.hh \
        dnslabeltext.cc
 
 htmlfiles.h: $(srcdir)/html/* $(srcdir)/incfiles
@@ -49,6 +55,11 @@ dnsdist-lua-ffi-interface.inc: dnsdist-lua-ffi-interface.h dnsdist-lua-inspectio
 SRC_JS_FILES := $(wildcard src_js/*.js)
 MIN_JS_FILES := $(patsubst src_js/%.js,html/js/%.min.js,$(SRC_JS_FILES))
 
+dnsdist%generated.cc dnsdist%generated.hh: dnsdist-rules-generator.py dnsdist-actions-definitions.yml dnsdist-response-actions-definitions.yml dnsdist-selectors-definitions.yml
+       @if test "$(PYTHON)" = ":"; then echo "Actions or selectors definitions have changed, python is needed to regenerate the related files but python was not found. Please install python and re-run configure"; exit 1; fi
+       @if ! $(PYTHON) --version | grep -q "Python 3"; then echo $(PYTHON) should be at least version 3. Please install python 3 and re-run configure; exit 1; fi
+       $(PYTHON) dnsdist-rules-generator.py
+
 html/js/%.min.js: src_js/%.js
        uglifyjs $< > $@
 
@@ -97,6 +108,15 @@ endif
 endif
 
 EXTRA_DIST=COPYING \
+          dnsdist-rules-generator.py \
+          dnsdist-actions-definitions.yml \
+          dnsdist-response-actions-definitions.yml \
+          dnsdist-rust-bridge.hh \
+          dnsdist-rust-bridge-actions-generated.cc \
+          dnsdist-rust-bridge-actions-generated.hh \
+          dnsdist-rust-bridge-selectors-generated.cc \
+          dnsdist-rust-bridge-selectors-generated.hh \
+          dnsdist-selectors-definitions.yml \
           dnslabeltext.rl \
           dnsdist.conf-dist \
           dnsmessage.proto \
@@ -151,6 +171,7 @@ dnsdist_SOURCES = \
        dns.cc dns.hh \
        dns_random.hh \
        dnscrypt.cc dnscrypt.hh \
+       dnsdist-actions-factory-generated.hh \
        dnsdist-actions.cc dnsdist-actions.hh \
        dnsdist-async.cc dnsdist-async.hh \
        dnsdist-backend.cc dnsdist-backend.hh \
@@ -214,6 +235,7 @@ dnsdist_SOURCES = \
        dnsdist-rules-factory.hh \
        dnsdist-rules.cc dnsdist-rules.hh \
        dnsdist-secpoll.cc dnsdist-secpoll.hh \
+       dnsdist-selectors-factory-generated.hh \
        dnsdist-self-answers.cc dnsdist-self-answers.hh \
        dnsdist-session-cache.cc dnsdist-session-cache.hh \
        dnsdist-snmp.cc dnsdist-snmp.hh \
diff --git a/pdns/dnsdistdist/dnsdist-actions-factory-generated.cc b/pdns/dnsdistdist/dnsdist-actions-factory-generated.cc
new file mode 100644 (file)
index 0000000..7c1f5a4
--- /dev/null
@@ -0,0 +1,101 @@
+// !! This file has been generated by dnsdist-rules-generator.py, do not edit by hand!!
+std::shared_ptr<DNSAction> getAllowAction()
+{
+  return std::shared_ptr<DNSAction>(new AllowAction());
+}
+std::shared_ptr<DNSAction> getDelayAction(uint32_t msec)
+{
+  return std::shared_ptr<DNSAction>(new DelayAction(msec));
+}
+std::shared_ptr<DNSAction> getDropAction()
+{
+  return std::shared_ptr<DNSAction>(new DropAction());
+}
+std::shared_ptr<DNSAction> getSetEDNSOptionAction(uint32_t code, const std::string& data)
+{
+  return std::shared_ptr<DNSAction>(new SetEDNSOptionAction(code, data));
+}
+std::shared_ptr<DNSAction> getLogAction(const std::string& fileName, bool binary, bool append, bool buffered, bool verboseOnly, bool includeTimestamp)
+{
+  return std::shared_ptr<DNSAction>(new LogAction(fileName, binary, append, buffered, verboseOnly, includeTimestamp));
+}
+std::shared_ptr<DNSAction> getLuaAction(dnsdist::actions::LuaActionFunction function)
+{
+  return std::shared_ptr<DNSAction>(new LuaAction(function));
+}
+std::shared_ptr<DNSAction> getLuaFFIAction(dnsdist::actions::LuaActionFFIFunction function)
+{
+  return std::shared_ptr<DNSAction>(new LuaFFIAction(function));
+}
+std::shared_ptr<DNSAction> getLuaFFIPerThreadAction(const std::string& code)
+{
+  return std::shared_ptr<DNSAction>(new LuaFFIPerThreadAction(code));
+}
+std::shared_ptr<DNSAction> getNoneAction()
+{
+  return std::shared_ptr<DNSAction>(new NoneAction());
+}
+std::shared_ptr<DNSAction> getPoolAction(const std::string& poolName, bool stopProcessing)
+{
+  return std::shared_ptr<DNSAction>(new PoolAction(poolName, stopProcessing));
+}
+std::shared_ptr<DNSAction> getQPSAction(uint32_t limit)
+{
+  return std::shared_ptr<DNSAction>(new QPSAction(limit));
+}
+std::shared_ptr<DNSAction> getQPSPoolAction(uint32_t limit, const std::string& poolName, bool stopProcessing)
+{
+  return std::shared_ptr<DNSAction>(new QPSPoolAction(limit, poolName, stopProcessing));
+}
+std::shared_ptr<DNSAction> getSetAdditionalProxyProtocolValueAction(uint8_t proxyType, const std::string& value)
+{
+  return std::shared_ptr<DNSAction>(new SetAdditionalProxyProtocolValueAction(proxyType, value));
+}
+std::shared_ptr<DNSAction> getSetDisableECSAction()
+{
+  return std::shared_ptr<DNSAction>(new SetDisableECSAction());
+}
+std::shared_ptr<DNSAction> getSetDisableValidationAction()
+{
+  return std::shared_ptr<DNSAction>(new SetDisableValidationAction());
+}
+std::shared_ptr<DNSAction> getSetECSOverrideAction(bool overrideExisting)
+{
+  return std::shared_ptr<DNSAction>(new SetECSOverrideAction(overrideExisting));
+}
+std::shared_ptr<DNSAction> getSetECSPrefixLengthAction(uint16_t ipv4, uint16_t ipv6)
+{
+  return std::shared_ptr<DNSAction>(new SetECSPrefixLengthAction(ipv4, ipv6));
+}
+std::shared_ptr<DNSAction> getSetExtendedDNSErrorAction(uint16_t infoCode, const std::string& extraText)
+{
+  return std::shared_ptr<DNSAction>(new SetExtendedDNSErrorAction(infoCode, extraText));
+}
+std::shared_ptr<DNSAction> getSetMacAddrAction(uint32_t code)
+{
+  return std::shared_ptr<DNSAction>(new SetMacAddrAction(code));
+}
+std::shared_ptr<DNSAction> getSetNoRecurseAction()
+{
+  return std::shared_ptr<DNSAction>(new SetNoRecurseAction());
+}
+std::shared_ptr<DNSAction> getSetSkipCacheAction()
+{
+  return std::shared_ptr<DNSAction>(new SetSkipCacheAction());
+}
+std::shared_ptr<DNSAction> getSetTagAction(const std::string& tag, const std::string& value)
+{
+  return std::shared_ptr<DNSAction>(new SetTagAction(tag, value));
+}
+std::shared_ptr<DNSAction> getSetTempFailureCacheTTLAction(uint32_t maxTTL)
+{
+  return std::shared_ptr<DNSAction>(new SetTempFailureCacheTTLAction(maxTTL));
+}
+std::shared_ptr<DNSAction> getSNMPTrapAction(const std::string& reason)
+{
+  return std::shared_ptr<DNSAction>(new SNMPTrapAction(reason));
+}
+std::shared_ptr<DNSAction> getTCAction()
+{
+  return std::shared_ptr<DNSAction>(new TCAction());
+}
diff --git a/pdns/dnsdistdist/dnsdist-actions-factory-generated.hh b/pdns/dnsdistdist/dnsdist-actions-factory-generated.hh
new file mode 100644 (file)
index 0000000..fb18c7b
--- /dev/null
@@ -0,0 +1,26 @@
+// !! This file has been generated by dnsdist-rules-generator.py, do not edit by hand!!
+std::shared_ptr<DNSAction> getAllowAction();
+std::shared_ptr<DNSAction> getDelayAction(uint32_t msec);
+std::shared_ptr<DNSAction> getDropAction();
+std::shared_ptr<DNSAction> getSetEDNSOptionAction(uint32_t code, const std::string& data);
+std::shared_ptr<DNSAction> getLogAction(const std::string& fileName, bool binary, bool append, bool buffered, bool verboseOnly, bool includeTimestamp);
+std::shared_ptr<DNSAction> getLuaAction(dnsdist::actions::LuaActionFunction function);
+std::shared_ptr<DNSAction> getLuaFFIAction(dnsdist::actions::LuaActionFFIFunction function);
+std::shared_ptr<DNSAction> getLuaFFIPerThreadAction(const std::string& code);
+std::shared_ptr<DNSAction> getNoneAction();
+std::shared_ptr<DNSAction> getPoolAction(const std::string& poolName, bool stopProcessing);
+std::shared_ptr<DNSAction> getQPSAction(uint32_t limit);
+std::shared_ptr<DNSAction> getQPSPoolAction(uint32_t limit, const std::string& poolName, bool stopProcessing);
+std::shared_ptr<DNSAction> getSetAdditionalProxyProtocolValueAction(uint8_t proxyType, const std::string& value);
+std::shared_ptr<DNSAction> getSetDisableECSAction();
+std::shared_ptr<DNSAction> getSetDisableValidationAction();
+std::shared_ptr<DNSAction> getSetECSOverrideAction(bool overrideExisting);
+std::shared_ptr<DNSAction> getSetECSPrefixLengthAction(uint16_t ipv4, uint16_t ipv6);
+std::shared_ptr<DNSAction> getSetExtendedDNSErrorAction(uint16_t infoCode, const std::string& extraText);
+std::shared_ptr<DNSAction> getSetMacAddrAction(uint32_t code);
+std::shared_ptr<DNSAction> getSetNoRecurseAction();
+std::shared_ptr<DNSAction> getSetSkipCacheAction();
+std::shared_ptr<DNSAction> getSetTagAction(const std::string& tag, const std::string& value);
+std::shared_ptr<DNSAction> getSetTempFailureCacheTTLAction(uint32_t maxTTL);
+std::shared_ptr<DNSAction> getSNMPTrapAction(const std::string& reason);
+std::shared_ptr<DNSAction> getTCAction();
diff --git a/pdns/dnsdistdist/dnsdist-lua-actions-generated.cc b/pdns/dnsdistdist/dnsdist-lua-actions-generated.cc
new file mode 100644 (file)
index 0000000..5123919
--- /dev/null
@@ -0,0 +1,76 @@
+// !! This file has been generated by dnsdist-rules-generator.py, do not edit by hand!!
+luaCtx.writeFunction("AllowAction", []() {
+  return dnsdist::actions::getAllowAction();
+});
+luaCtx.writeFunction("DelayAction", [](uint32_t msec) {
+  return dnsdist::actions::getDelayAction(msec);
+});
+luaCtx.writeFunction("DropAction", []() {
+  return dnsdist::actions::getDropAction();
+});
+luaCtx.writeFunction("SetEDNSOptionAction", [](uint32_t code, std::string data) {
+  return dnsdist::actions::getSetEDNSOptionAction(code, data);
+});
+luaCtx.writeFunction("LogAction", [](boost::optional<std::string> fileName, boost::optional<bool> binary, boost::optional<bool> append, boost::optional<bool> buffered, boost::optional<bool> verboseOnly, boost::optional<bool> includeTimestamp) {
+  return dnsdist::actions::getLogAction(fileName ? *fileName : "", binary ? *binary : true, append ? *append : false, buffered ? *buffered : false, verboseOnly ? *verboseOnly : true, includeTimestamp ? *includeTimestamp : false);
+});
+luaCtx.writeFunction("LuaAction", [](dnsdist::actions::LuaActionFunction function) {
+  return dnsdist::actions::getLuaAction(function);
+});
+luaCtx.writeFunction("LuaFFIAction", [](dnsdist::actions::LuaActionFFIFunction function) {
+  return dnsdist::actions::getLuaFFIAction(function);
+});
+luaCtx.writeFunction("LuaFFIPerThreadAction", [](std::string code) {
+  return dnsdist::actions::getLuaFFIPerThreadAction(code);
+});
+luaCtx.writeFunction("NoneAction", []() {
+  return dnsdist::actions::getNoneAction();
+});
+luaCtx.writeFunction("PoolAction", [](std::string poolName, boost::optional<bool> stopProcessing) {
+  return dnsdist::actions::getPoolAction(poolName, stopProcessing ? *stopProcessing : true);
+});
+luaCtx.writeFunction("QPSAction", [](uint32_t limit) {
+  return dnsdist::actions::getQPSAction(limit);
+});
+luaCtx.writeFunction("QPSPoolAction", [](uint32_t limit, std::string poolName, boost::optional<bool> stopProcessing) {
+  return dnsdist::actions::getQPSPoolAction(limit, poolName, stopProcessing ? *stopProcessing : true);
+});
+luaCtx.writeFunction("SetAdditionalProxyProtocolValueAction", [](uint8_t proxyType, std::string value) {
+  return dnsdist::actions::getSetAdditionalProxyProtocolValueAction(proxyType, value);
+});
+luaCtx.writeFunction("SetDisableECSAction", []() {
+  return dnsdist::actions::getSetDisableECSAction();
+});
+luaCtx.writeFunction("SetDisableValidationAction", []() {
+  return dnsdist::actions::getSetDisableValidationAction();
+});
+luaCtx.writeFunction("SetECSOverrideAction", [](bool overrideExisting) {
+  return dnsdist::actions::getSetECSOverrideAction(overrideExisting);
+});
+luaCtx.writeFunction("SetECSPrefixLengthAction", [](uint16_t ipv4, uint16_t ipv6) {
+  return dnsdist::actions::getSetECSPrefixLengthAction(ipv4, ipv6);
+});
+luaCtx.writeFunction("SetExtendedDNSErrorAction", [](uint16_t infoCode, boost::optional<std::string> extraText) {
+  return dnsdist::actions::getSetExtendedDNSErrorAction(infoCode, extraText ? *extraText : "");
+});
+luaCtx.writeFunction("SetMacAddrAction", [](uint32_t code) {
+  return dnsdist::actions::getSetMacAddrAction(code);
+});
+luaCtx.writeFunction("SetNoRecurseAction", []() {
+  return dnsdist::actions::getSetNoRecurseAction();
+});
+luaCtx.writeFunction("SetSkipCacheAction", []() {
+  return dnsdist::actions::getSetSkipCacheAction();
+});
+luaCtx.writeFunction("SetTagAction", [](std::string tag, std::string value) {
+  return dnsdist::actions::getSetTagAction(tag, value);
+});
+luaCtx.writeFunction("SetTempFailureCacheTTLAction", [](uint32_t maxTTL) {
+  return dnsdist::actions::getSetTempFailureCacheTTLAction(maxTTL);
+});
+luaCtx.writeFunction("SNMPTrapAction", [](boost::optional<std::string> reason) {
+  return dnsdist::actions::getSNMPTrapAction(reason ? *reason : "");
+});
+luaCtx.writeFunction("TCAction", []() {
+  return dnsdist::actions::getTCAction();
+});
diff --git a/pdns/dnsdistdist/dnsdist-lua-response-actions-generated.cc b/pdns/dnsdistdist/dnsdist-lua-response-actions-generated.cc
new file mode 100644 (file)
index 0000000..bc5a13b
--- /dev/null
@@ -0,0 +1,40 @@
+// !! This file has been generated by dnsdist-rules-generator.py, do not edit by hand!!
+luaCtx.writeFunction("AllowResponseAction", []() {
+  return dnsdist::actions::getAllowResponseAction();
+});
+luaCtx.writeFunction("DelayResponseAction", [](uint32_t msec) {
+  return dnsdist::actions::getDelayResponseAction(msec);
+});
+luaCtx.writeFunction("DropResponseAction", []() {
+  return dnsdist::actions::getDropResponseAction();
+});
+luaCtx.writeFunction("LogResponseAction", [](boost::optional<std::string> fileName, boost::optional<bool> append, boost::optional<bool> buffered, boost::optional<bool> verboseOnly, boost::optional<bool> includeTimestamp) {
+  return dnsdist::actions::getLogResponseAction(fileName ? *fileName : "", append ? *append : false, buffered ? *buffered : false, verboseOnly ? *verboseOnly : true, includeTimestamp ? *includeTimestamp : false);
+});
+luaCtx.writeFunction("LuaResponseAction", [](dnsdist::actions::LuaResponseActionFunction function) {
+  return dnsdist::actions::getLuaResponseAction(function);
+});
+luaCtx.writeFunction("LuaFFIResponseAction", [](dnsdist::actions::LuaResponseActionFFIFunction function) {
+  return dnsdist::actions::getLuaFFIResponseAction(function);
+});
+luaCtx.writeFunction("LuaFFIPerThreadResponseAction", [](std::string code) {
+  return dnsdist::actions::getLuaFFIPerThreadResponseAction(code);
+});
+luaCtx.writeFunction("SetExtendedDNSErrorResponseAction", [](uint16_t infoCode, boost::optional<std::string> extraText) {
+  return dnsdist::actions::getSetExtendedDNSErrorResponseAction(infoCode, extraText ? *extraText : "");
+});
+luaCtx.writeFunction("SetReducedTTLResponseAction", [](uint8_t percentage) {
+  return dnsdist::actions::getSetReducedTTLResponseAction(percentage);
+});
+luaCtx.writeFunction("SetSkipCacheResponseAction", []() {
+  return dnsdist::actions::getSetSkipCacheResponseAction();
+});
+luaCtx.writeFunction("SetTagResponseAction", [](std::string tag, std::string value) {
+  return dnsdist::actions::getSetTagResponseAction(tag, value);
+});
+luaCtx.writeFunction("SNMPTrapResponseAction", [](boost::optional<std::string> reason) {
+  return dnsdist::actions::getSNMPTrapResponseAction(reason ? *reason : "");
+});
+luaCtx.writeFunction("TCResponseAction", []() {
+  return dnsdist::actions::getTCResponseAction();
+});
diff --git a/pdns/dnsdistdist/dnsdist-lua-selectors-generated.cc b/pdns/dnsdistdist/dnsdist-lua-selectors-generated.cc
new file mode 100644 (file)
index 0000000..d16d905
--- /dev/null
@@ -0,0 +1,97 @@
+// !! This file has been generated by dnsdist-rules-generator.py, do not edit by hand!!
+luaCtx.writeFunction("AllRule", []() {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getAllSelector());
+});
+luaCtx.writeFunction("DNSSECRule", []() {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getDNSSECSelector());
+});
+luaCtx.writeFunction("DSTPortRule", [](uint16_t port) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getDSTPortSelector(port));
+});
+luaCtx.writeFunction("EDNSOptionRule", [](uint16_t optionCode) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getEDNSOptionSelector(optionCode));
+});
+luaCtx.writeFunction("EDNSVersionRule", [](uint8_t version) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getEDNSVersionSelector(version));
+});
+luaCtx.writeFunction("ERCodeRule", [](uint64_t rcode) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getERCodeSelector(rcode));
+});
+luaCtx.writeFunction("HTTPHeaderRule", [](std::string header, std::string expression) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getHTTPHeaderSelector(header, expression));
+});
+luaCtx.writeFunction("HTTPPathRule", [](std::string path) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getHTTPPathSelector(path));
+});
+luaCtx.writeFunction("HTTPPathRegexRule", [](std::string expression) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getHTTPPathRegexSelector(expression));
+});
+luaCtx.writeFunction("LuaRule", [](dnsdist::selectors::LuaSelectorFunction function) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getLuaSelector(function));
+});
+luaCtx.writeFunction("LuaFFIRule", [](dnsdist::selectors::LuaSelectorFFIFunction function) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getLuaFFISelector(function));
+});
+luaCtx.writeFunction("LuaFFIPerThreadRule", [](std::string code) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getLuaFFIPerThreadSelector(code));
+});
+luaCtx.writeFunction("MaxQPSRule", [](uint32_t qps, boost::optional<uint32_t> burst) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getMaxQPSSelector(qps, boostToStandardOptional(burst)));
+});
+luaCtx.writeFunction("MaxQPSIPRule", [](uint32_t qps, boost::optional<uint8_t> ipv4Mask, boost::optional<uint8_t> ipv6Mask, boost::optional<uint32_t> burst, boost::optional<uint32_t> expiration, boost::optional<uint32_t> cleanupDelay, boost::optional<uint32_t> scanFraction, boost::optional<uint32_t> shards) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getMaxQPSIPSelector(qps, boostToStandardOptional(ipv4Mask), boostToStandardOptional(ipv6Mask), boostToStandardOptional(burst), boostToStandardOptional(expiration), boostToStandardOptional(cleanupDelay), boostToStandardOptional(scanFraction), boostToStandardOptional(shards)));
+});
+luaCtx.writeFunction("OpcodeRule", [](uint8_t code) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getOpcodeSelector(code));
+});
+luaCtx.writeFunction("PayloadSizeRule", [](std::string comparison, uint16_t size) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getPayloadSizeSelector(comparison, size));
+});
+luaCtx.writeFunction("PoolAvailableRule", [](std::string pool) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getPoolAvailableSelector(pool));
+});
+luaCtx.writeFunction("PoolOutstandingRule", [](std::string pool, uint64_t maxOutstanding) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getPoolOutstandingSelector(pool, maxOutstanding));
+});
+luaCtx.writeFunction("ProbaRule", [](double probability) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getProbaSelector(probability));
+});
+luaCtx.writeFunction("ProxyProtocolValueRule", [](uint8_t optionType, boost::optional<std::string> optionValue) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getProxyProtocolValueSelector(optionType, boostToStandardOptional(optionValue)));
+});
+luaCtx.writeFunction("QNameLabelsCountRule", [](uint16_t minLabelsCount, uint16_t maxLabelsCount) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getQNameLabelsCountSelector(minLabelsCount, maxLabelsCount));
+});
+luaCtx.writeFunction("QNameWireLengthRule", [](uint16_t min, uint16_t max) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getQNameWireLengthSelector(min, max));
+});
+luaCtx.writeFunction("RCodeRule", [](uint64_t rcode) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getRCodeSelector(rcode));
+});
+luaCtx.writeFunction("RDRule", []() {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getRDSelector());
+});
+luaCtx.writeFunction("RE2Rule", [](std::string expression) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getRE2Selector(expression));
+});
+luaCtx.writeFunction("RecordsCountRule", [](uint8_t section, uint16_t minimum, uint16_t maximum) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getRecordsCountSelector(section, minimum, maximum));
+});
+luaCtx.writeFunction("RecordsTypeCountRule", [](uint8_t section, uint16_t recordType, uint16_t minimum, uint16_t maximum) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getRecordsTypeCountSelector(section, recordType, minimum, maximum));
+});
+luaCtx.writeFunction("RegexRule", [](std::string expression) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getRegexSelector(expression));
+});
+luaCtx.writeFunction("SNIRule", [](std::string serverName) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getSNISelector(serverName));
+});
+luaCtx.writeFunction("TagRule", [](std::string tag, boost::optional<std::string> value) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getTagSelector(tag, boostToStandardOptional(value)));
+});
+luaCtx.writeFunction("TCPRule", [](bool tcp) {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getTCPSelector(tcp));
+});
+luaCtx.writeFunction("TrailingDataRule", []() {
+  return std::shared_ptr<DNSRule>(dnsdist::selectors::getTrailingDataSelector());
+});
diff --git a/pdns/dnsdistdist/dnsdist-response-actions-factory-generated.cc b/pdns/dnsdistdist/dnsdist-response-actions-factory-generated.cc
new file mode 100644 (file)
index 0000000..3066ffb
--- /dev/null
@@ -0,0 +1,53 @@
+// !! This file has been generated by dnsdist-rules-generator.py, do not edit by hand!!
+std::shared_ptr<DNSResponseAction> getAllowResponseAction()
+{
+  return std::shared_ptr<DNSResponseAction>(new AllowResponseAction());
+}
+std::shared_ptr<DNSResponseAction> getDelayResponseAction(uint32_t msec)
+{
+  return std::shared_ptr<DNSResponseAction>(new DelayResponseAction(msec));
+}
+std::shared_ptr<DNSResponseAction> getDropResponseAction()
+{
+  return std::shared_ptr<DNSResponseAction>(new DropResponseAction());
+}
+std::shared_ptr<DNSResponseAction> getLogResponseAction(const std::string& fileName, bool append, bool buffered, bool verboseOnly, bool includeTimestamp)
+{
+  return std::shared_ptr<DNSResponseAction>(new LogResponseAction(fileName, append, buffered, verboseOnly, includeTimestamp));
+}
+std::shared_ptr<DNSResponseAction> getLuaResponseAction(dnsdist::actions::LuaResponseActionFunction function)
+{
+  return std::shared_ptr<DNSResponseAction>(new LuaResponseAction(function));
+}
+std::shared_ptr<DNSResponseAction> getLuaFFIResponseAction(dnsdist::actions::LuaResponseActionFFIFunction function)
+{
+  return std::shared_ptr<DNSResponseAction>(new LuaFFIResponseAction(function));
+}
+std::shared_ptr<DNSResponseAction> getLuaFFIPerThreadResponseAction(const std::string& code)
+{
+  return std::shared_ptr<DNSResponseAction>(new LuaFFIPerThreadResponseAction(code));
+}
+std::shared_ptr<DNSResponseAction> getSetExtendedDNSErrorResponseAction(uint16_t infoCode, const std::string& extraText)
+{
+  return std::shared_ptr<DNSResponseAction>(new SetExtendedDNSErrorResponseAction(infoCode, extraText));
+}
+std::shared_ptr<DNSResponseAction> getSetReducedTTLResponseAction(uint8_t percentage)
+{
+  return std::shared_ptr<DNSResponseAction>(new SetReducedTTLResponseAction(percentage));
+}
+std::shared_ptr<DNSResponseAction> getSetSkipCacheResponseAction()
+{
+  return std::shared_ptr<DNSResponseAction>(new SetSkipCacheResponseAction());
+}
+std::shared_ptr<DNSResponseAction> getSetTagResponseAction(const std::string& tag, const std::string& value)
+{
+  return std::shared_ptr<DNSResponseAction>(new SetTagResponseAction(tag, value));
+}
+std::shared_ptr<DNSResponseAction> getSNMPTrapResponseAction(const std::string& reason)
+{
+  return std::shared_ptr<DNSResponseAction>(new SNMPTrapResponseAction(reason));
+}
+std::shared_ptr<DNSResponseAction> getTCResponseAction()
+{
+  return std::shared_ptr<DNSResponseAction>(new TCResponseAction());
+}
diff --git a/pdns/dnsdistdist/dnsdist-response-actions-factory-generated.hh b/pdns/dnsdistdist/dnsdist-response-actions-factory-generated.hh
new file mode 100644 (file)
index 0000000..839dbaf
--- /dev/null
@@ -0,0 +1,14 @@
+// !! This file has been generated by dnsdist-rules-generator.py, do not edit by hand!!
+std::shared_ptr<DNSResponseAction> getAllowResponseAction();
+std::shared_ptr<DNSResponseAction> getDelayResponseAction(uint32_t msec);
+std::shared_ptr<DNSResponseAction> getDropResponseAction();
+std::shared_ptr<DNSResponseAction> getLogResponseAction(const std::string& fileName, bool append, bool buffered, bool verboseOnly, bool includeTimestamp);
+std::shared_ptr<DNSResponseAction> getLuaResponseAction(dnsdist::actions::LuaResponseActionFunction function);
+std::shared_ptr<DNSResponseAction> getLuaFFIResponseAction(dnsdist::actions::LuaResponseActionFFIFunction function);
+std::shared_ptr<DNSResponseAction> getLuaFFIPerThreadResponseAction(const std::string& code);
+std::shared_ptr<DNSResponseAction> getSetExtendedDNSErrorResponseAction(uint16_t infoCode, const std::string& extraText);
+std::shared_ptr<DNSResponseAction> getSetReducedTTLResponseAction(uint8_t percentage);
+std::shared_ptr<DNSResponseAction> getSetSkipCacheResponseAction();
+std::shared_ptr<DNSResponseAction> getSetTagResponseAction(const std::string& tag, const std::string& value);
+std::shared_ptr<DNSResponseAction> getSNMPTrapResponseAction(const std::string& reason);
+std::shared_ptr<DNSResponseAction> getTCResponseAction();
diff --git a/pdns/dnsdistdist/dnsdist-rules-generator.py b/pdns/dnsdistdist/dnsdist-rules-generator.py
new file mode 100644 (file)
index 0000000..cb6c0d7
--- /dev/null
@@ -0,0 +1,285 @@
+#!/usr/bin/python3
+"""Load action and selector definitions and generates C++ factory and Lua bindings code."""
+# 1/ Loads the action definitions from:
+# - dnsdist-actions-definitions.yml
+# - dnsdist-response-actions-definitions.yml
+# and generates C++ factory to create the objects
+# for these actions from the corresponding parameters:
+# - dnsdist-actions-factory-generated.cc
+# - dnsdist-actions-factory-generated.hh
+# - dnsdist-response-actions-factory-generated.cc
+# - dnsdist-response-actions-factory-generated.hh
+# as well as Lua bindings for them:
+# - dnsdist-lua-actions-generated.cc
+# - dnsdist-lua-response-actions-generated.cc
+# 2/ Loads the selector definitions from:
+# - dnsdist-selectors-definitions.yml
+# and generates C++ factory to create the objects
+# for these selectors from the corresponding parameters:
+# - dnsdist-selectors-factory-generated.cc
+# - dnsdist-selectors-factory-generated.hh
+# as well as the Lua bindings for them:
+# - dnsdist-lua-selectors-generated.cc
+# The format of the definitions, in YAML, is a simple list of items.
+# Each item has a name and an optional list of parameters.
+# Parameters have a name, a type, and optionally a default value
+# Types are the Rust ones, converted to the C++ equivalent when needed
+# Default values are written as quoted strings, with the exception of the
+# special unquoted true value which means to use the default value for the
+# object type, which needs to exist.
+# Items can optionally have the following properties:
+# - 'skip-cpp' means that the corresponding C++ factory and Lua bindinds will not be generated, which is useful for objects taking parameters that cannot be directly mapped
+# - 'skip-rust' is not used by this script but is used by the dnsdist-settings-generator.py one, where it means that the C++ code to create the Rust-side version of an action or selector will not generated
+# - 'skip-serde' is not used by this script but is used by the dnsdist-settings-generator.py one, where it means that the Rust structure representing that action or selector in the YAML setting will not be directly created by Serde. It is used for selectors that reference another selector themselves, or actions referencing another action.
+import os
+import tempfile
+import yaml
+
+def get_definitions_from_file(def_file):
+    with open(def_file, 'rt', encoding="utf-8") as fd:
+        definitions = yaml.safe_load(fd.read())
+        return definitions
+
+def is_vector_of(type_str):
+    return type_str.startswith('Vec<')
+
+def type_to_cpp(type_str, lua_interface, inside_container=False):
+    if is_vector_of(type_str):
+        sub_type = type_str[4:-1]
+        return 'std::vector<' + type_to_cpp(sub_type, lua_interface, True) + '>'
+
+    if type_str == 'u8':
+        return 'uint8_t'
+    if type_str == 'u16':
+        return 'uint16_t'
+    if type_str == 'u32':
+        return 'uint32_t'
+    if type_str == 'u64':
+        return 'uint64_t'
+    if type_str == 'f64':
+        return 'double'
+    if type_str == 'String':
+        if lua_interface:
+            return 'std::string'
+        if inside_container:
+            return 'std::string'
+        return 'const std::string&'
+    return type_str
+
+def get_cpp_object_name(name, is_class=True):
+    object_name = ''
+    capitalize = is_class
+    for char in name:
+        if char == '-':
+            capitalize = True
+            continue
+        if capitalize:
+            char = char.upper()
+            capitalize = False
+        object_name += char
+
+    return object_name
+
+def get_cpp_parameter_name(name):
+    return get_cpp_object_name(name, is_class=False)
+
+def get_cpp_parameters_definition(parameters, lua_interface):
+    output = ''
+    for parameter in parameters:
+        pname = get_cpp_parameter_name(parameter['name'])
+        ptype = type_to_cpp(parameter['type'], lua_interface)
+        if 'default' in parameter:
+            if lua_interface:
+                ptype = type_to_cpp(parameter['type'], lua_interface, True)
+                ptype = f'boost::optional<{ptype}>'
+            elif not 'cpp-optional' in parameter or parameter['cpp-optional']:
+                ptype = type_to_cpp(parameter['type'], lua_interface, True)
+                ptype = f'std::optional<{ptype}>'
+        if len(output) > 0:
+            output += ', '
+        output += f'{ptype} {pname}'
+    return output
+
+def get_cpp_parameters(parameters, lua_interface):
+    output = ''
+    for parameter in parameters:
+        pname = get_cpp_parameter_name(parameter['name'])
+        if len(output) > 0:
+            output += ', '
+        default = None
+        if not 'default' in parameter:
+            output += f'{pname}'
+            continue
+
+        cpp_optional = not 'cpp-optional' in parameter or parameter['cpp-optional']
+        if lua_interface and not cpp_optional:
+            # We are the Lua binding, and the factory does not handle optional values
+            # -> pass the value if any, and the default otherwise
+            default = parameter['default']
+        elif lua_interface and cpp_optional:
+            # we are the Lua binding, the factory does handle optional values,
+            # -> boost::optional to std::optional
+            output += f'boostToStandardOptional({pname})'
+            continue
+        elif not lua_interface and cpp_optional:
+            # We are the C++ factory and we do handle optional values
+            # -> pass the value if any, and the default otherwise
+            default = parameter['default']
+        else:
+            # We are the C++ factory and we do not handle optional values
+            # -> pass the value we received
+            output += f'{pname}'
+            continue
+
+        if default == '':
+            default = '""'
+        if default == True:
+            default = '{}'
+
+        output += f'{pname} ? *{pname} : {default}'
+
+    return output
+
+def get_temporary_file_for_generated_code():
+    generated_fp = tempfile.NamedTemporaryFile(mode='w+t', encoding='utf-8', dir='.', delete=False)
+    generated_fp.write('// !! This file has been generated by dnsdist-rules-generator.py, do not edit by hand!!\n')
+    return generated_fp
+
+def generate_actions_factory_header(definitions, response=False):
+    suffix = 'ResponseAction' if response else 'Action'
+    shared_object_type = f'DNS{suffix}'
+    generated_fp = get_temporary_file_for_generated_code()
+
+    for action in definitions:
+        if 'skip-cpp' in action and action['skip-cpp']:
+            continue
+        name = get_cpp_object_name(action['name'])
+        output = f'std::shared_ptr<{shared_object_type}> get{name}{suffix}('
+        if 'parameters' in action:
+            output += get_cpp_parameters_definition(action['parameters'], False)
+        output += ');\n'
+        generated_fp.write(output)
+
+    output_file_name = 'dnsdist-response-actions-factory-generated.hh' if response else 'dnsdist-actions-factory-generated.hh'
+    os.rename(generated_fp.name, output_file_name)
+
+def generate_actions_factory(definitions, response=False):
+    suffix = 'ResponseAction' if response else 'Action'
+    generated_fp = get_temporary_file_for_generated_code()
+
+    for action in definitions:
+        if 'skip-cpp' in action and action['skip-cpp']:
+            continue
+        name = get_cpp_object_name(action['name'])
+        output = f'std::shared_ptr<DNS{suffix}> get{name}{suffix}('
+        if 'parameters' in action:
+            output += get_cpp_parameters_definition(action['parameters'], False)
+        output += ')\n{\n'
+        output += f'  return std::shared_ptr<DNS{suffix}>(new {name}{suffix}('
+        if 'parameters' in action:
+            output += get_cpp_parameters(action['parameters'], False)
+        output += '));\n'
+        output += '}\n'
+        generated_fp.write(output)
+
+    output_file_name = 'dnsdist-response-actions-factory-generated.cc' if response else 'dnsdist-actions-factory-generated.cc'
+    os.rename(generated_fp.name, output_file_name)
+
+def generate_lua_actions_bindings(definitions, response=False):
+    suffix = 'ResponseAction' if response else 'Action'
+    generated_fp = get_temporary_file_for_generated_code()
+
+    for action in definitions:
+        if 'skip-cpp' in action and action['skip-cpp']:
+            continue
+        name = get_cpp_object_name(action['name'])
+        output = f'luaCtx.writeFunction("{name}{suffix}", []('
+        if 'parameters' in action:
+            output += get_cpp_parameters_definition(action['parameters'], True)
+        output += ') {\n'
+        output += f'  return dnsdist::actions::get{name}{suffix}('
+        if 'parameters' in action:
+            output += get_cpp_parameters(action['parameters'], True)
+        output += ');\n'
+        output += '});\n'
+        generated_fp.write(output)
+
+    output_file_name = 'dnsdist-lua-response-actions-generated.cc' if response else 'dnsdist-lua-actions-generated.cc'
+    os.rename(generated_fp.name, output_file_name)
+
+def generate_selectors_factory_header(definitions):
+    generated_fp = get_temporary_file_for_generated_code()
+
+    for selector in definitions:
+        if 'skip-cpp' in selector and selector['skip-cpp']:
+            continue
+        name = get_cpp_object_name(selector['name'])
+        output = f'std::shared_ptr<{name}Rule> get{name}Selector('
+        if 'parameters' in selector:
+            output += get_cpp_parameters_definition(selector['parameters'], False)
+        output += ');\n'
+        generated_fp.write(output)
+
+    output_file_name = 'dnsdist-selectors-factory-generated.hh'
+    os.rename(generated_fp.name, output_file_name)
+
+def generate_selectors_factory(definitions, response=False):
+    generated_fp = get_temporary_file_for_generated_code()
+
+    for selector in definitions:
+        if 'skip-cpp' in selector and selector['skip-cpp']:
+            continue
+        name = get_cpp_object_name(selector['name'])
+        output = f'std::shared_ptr<{name}Rule> get{name}Selector('
+        if 'parameters' in selector:
+            output += get_cpp_parameters_definition(selector['parameters'], False)
+        output += ')\n{\n'
+        output += f'  return std::make_shared<{name}Rule>('
+        if 'parameters' in selector:
+            output += get_cpp_parameters(selector['parameters'], False)
+        output += ');\n'
+        output += '}\n'
+        generated_fp.write(output)
+
+    output_file_name = 'dnsdist-selectors-factory-generated.cc'
+    os.rename(generated_fp.name, output_file_name)
+
+def generate_lua_selectors_bindings(definitions):
+    generated_fp = get_temporary_file_for_generated_code()
+
+    for selector in definitions:
+        if 'skip-cpp' in selector and selector['skip-cpp']:
+            continue
+        name = get_cpp_object_name(selector['name'])
+        output = f'luaCtx.writeFunction("{name}Rule", []('
+        if 'parameters' in selector:
+            output += get_cpp_parameters_definition(selector['parameters'], True)
+        output += ') {\n'
+        output += f'  return std::shared_ptr<DNSRule>(dnsdist::selectors::get{name}Selector('
+        if 'parameters' in selector:
+            output += get_cpp_parameters(selector['parameters'], True)
+        output += '));\n'
+        output += '});\n'
+        generated_fp.write(output)
+
+    output_file_name = 'dnsdist-lua-selectors-generated.cc'
+    os.rename(generated_fp.name, output_file_name)
+
+def main():
+    definitions = get_definitions_from_file('dnsdist-actions-definitions.yml')
+    generate_actions_factory_header(definitions)
+    generate_actions_factory(definitions)
+    generate_lua_actions_bindings(definitions)
+
+    definitions = get_definitions_from_file('dnsdist-response-actions-definitions.yml')
+    generate_actions_factory_header(definitions, response=True)
+    generate_actions_factory(definitions, response=True)
+    generate_lua_actions_bindings(definitions, response=True)
+
+    definitions = get_definitions_from_file('dnsdist-selectors-definitions.yml')
+    generate_selectors_factory_header(definitions)
+    generate_selectors_factory(definitions)
+    generate_lua_selectors_bindings(definitions)
+
+if __name__ == '__main__':
+    main()
diff --git a/pdns/dnsdistdist/dnsdist-selectors-factory-generated.cc b/pdns/dnsdistdist/dnsdist-selectors-factory-generated.cc
new file mode 100644 (file)
index 0000000..224ff58
--- /dev/null
@@ -0,0 +1,129 @@
+// !! This file has been generated by dnsdist-rules-generator.py, do not edit by hand!!
+std::shared_ptr<AllRule> getAllSelector()
+{
+  return std::make_shared<AllRule>();
+}
+std::shared_ptr<DNSSECRule> getDNSSECSelector()
+{
+  return std::make_shared<DNSSECRule>();
+}
+std::shared_ptr<DSTPortRule> getDSTPortSelector(uint16_t port)
+{
+  return std::make_shared<DSTPortRule>(port);
+}
+std::shared_ptr<EDNSOptionRule> getEDNSOptionSelector(uint16_t optionCode)
+{
+  return std::make_shared<EDNSOptionRule>(optionCode);
+}
+std::shared_ptr<EDNSVersionRule> getEDNSVersionSelector(uint8_t version)
+{
+  return std::make_shared<EDNSVersionRule>(version);
+}
+std::shared_ptr<ERCodeRule> getERCodeSelector(uint64_t rcode)
+{
+  return std::make_shared<ERCodeRule>(rcode);
+}
+std::shared_ptr<HTTPHeaderRule> getHTTPHeaderSelector(const std::string& header, const std::string& expression)
+{
+  return std::make_shared<HTTPHeaderRule>(header, expression);
+}
+std::shared_ptr<HTTPPathRule> getHTTPPathSelector(const std::string& path)
+{
+  return std::make_shared<HTTPPathRule>(path);
+}
+std::shared_ptr<HTTPPathRegexRule> getHTTPPathRegexSelector(const std::string& expression)
+{
+  return std::make_shared<HTTPPathRegexRule>(expression);
+}
+std::shared_ptr<LuaRule> getLuaSelector(dnsdist::selectors::LuaSelectorFunction function)
+{
+  return std::make_shared<LuaRule>(function);
+}
+std::shared_ptr<LuaFFIRule> getLuaFFISelector(dnsdist::selectors::LuaSelectorFFIFunction function)
+{
+  return std::make_shared<LuaFFIRule>(function);
+}
+std::shared_ptr<LuaFFIPerThreadRule> getLuaFFIPerThreadSelector(const std::string& code)
+{
+  return std::make_shared<LuaFFIPerThreadRule>(code);
+}
+std::shared_ptr<MaxQPSRule> getMaxQPSSelector(uint32_t qps, std::optional<uint32_t> burst)
+{
+  return std::make_shared<MaxQPSRule>(qps, burst ? *burst : 0);
+}
+std::shared_ptr<MaxQPSIPRule> getMaxQPSIPSelector(uint32_t qps, std::optional<uint8_t> ipv4Mask, std::optional<uint8_t> ipv6Mask, std::optional<uint32_t> burst, std::optional<uint32_t> expiration, std::optional<uint32_t> cleanupDelay, std::optional<uint32_t> scanFraction, std::optional<uint32_t> shards)
+{
+  return std::make_shared<MaxQPSIPRule>(qps, ipv4Mask ? *ipv4Mask : 32, ipv6Mask ? *ipv6Mask : 64, burst ? *burst : 0, expiration ? *expiration : 300, cleanupDelay ? *cleanupDelay : 60, scanFraction ? *scanFraction : 10, shards ? *shards : 10);
+}
+std::shared_ptr<OpcodeRule> getOpcodeSelector(uint8_t code)
+{
+  return std::make_shared<OpcodeRule>(code);
+}
+std::shared_ptr<PayloadSizeRule> getPayloadSizeSelector(const std::string& comparison, uint16_t size)
+{
+  return std::make_shared<PayloadSizeRule>(comparison, size);
+}
+std::shared_ptr<PoolAvailableRule> getPoolAvailableSelector(const std::string& pool)
+{
+  return std::make_shared<PoolAvailableRule>(pool);
+}
+std::shared_ptr<PoolOutstandingRule> getPoolOutstandingSelector(const std::string& pool, uint64_t maxOutstanding)
+{
+  return std::make_shared<PoolOutstandingRule>(pool, maxOutstanding);
+}
+std::shared_ptr<ProbaRule> getProbaSelector(double probability)
+{
+  return std::make_shared<ProbaRule>(probability);
+}
+std::shared_ptr<ProxyProtocolValueRule> getProxyProtocolValueSelector(uint8_t optionType, std::optional<std::string> optionValue)
+{
+  return std::make_shared<ProxyProtocolValueRule>(optionType, optionValue ? *optionValue : "");
+}
+std::shared_ptr<QNameLabelsCountRule> getQNameLabelsCountSelector(uint16_t minLabelsCount, uint16_t maxLabelsCount)
+{
+  return std::make_shared<QNameLabelsCountRule>(minLabelsCount, maxLabelsCount);
+}
+std::shared_ptr<QNameWireLengthRule> getQNameWireLengthSelector(uint16_t min, uint16_t max)
+{
+  return std::make_shared<QNameWireLengthRule>(min, max);
+}
+std::shared_ptr<RCodeRule> getRCodeSelector(uint64_t rcode)
+{
+  return std::make_shared<RCodeRule>(rcode);
+}
+std::shared_ptr<RDRule> getRDSelector()
+{
+  return std::make_shared<RDRule>();
+}
+std::shared_ptr<RE2Rule> getRE2Selector(const std::string& expression)
+{
+  return std::make_shared<RE2Rule>(expression);
+}
+std::shared_ptr<RecordsCountRule> getRecordsCountSelector(uint8_t section, uint16_t minimum, uint16_t maximum)
+{
+  return std::make_shared<RecordsCountRule>(section, minimum, maximum);
+}
+std::shared_ptr<RecordsTypeCountRule> getRecordsTypeCountSelector(uint8_t section, uint16_t recordType, uint16_t minimum, uint16_t maximum)
+{
+  return std::make_shared<RecordsTypeCountRule>(section, recordType, minimum, maximum);
+}
+std::shared_ptr<RegexRule> getRegexSelector(const std::string& expression)
+{
+  return std::make_shared<RegexRule>(expression);
+}
+std::shared_ptr<SNIRule> getSNISelector(const std::string& serverName)
+{
+  return std::make_shared<SNIRule>(serverName);
+}
+std::shared_ptr<TagRule> getTagSelector(const std::string& tag, std::optional<std::string> value)
+{
+  return std::make_shared<TagRule>(tag, value ? *value : "");
+}
+std::shared_ptr<TCPRule> getTCPSelector(bool tcp)
+{
+  return std::make_shared<TCPRule>(tcp);
+}
+std::shared_ptr<TrailingDataRule> getTrailingDataSelector()
+{
+  return std::make_shared<TrailingDataRule>();
+}
diff --git a/pdns/dnsdistdist/dnsdist-selectors-factory-generated.hh b/pdns/dnsdistdist/dnsdist-selectors-factory-generated.hh
new file mode 100644 (file)
index 0000000..fe48132
--- /dev/null
@@ -0,0 +1,33 @@
+// !! This file has been generated by dnsdist-rules-generator.py, do not edit by hand!!
+std::shared_ptr<AllRule> getAllSelector();
+std::shared_ptr<DNSSECRule> getDNSSECSelector();
+std::shared_ptr<DSTPortRule> getDSTPortSelector(uint16_t port);
+std::shared_ptr<EDNSOptionRule> getEDNSOptionSelector(uint16_t optionCode);
+std::shared_ptr<EDNSVersionRule> getEDNSVersionSelector(uint8_t version);
+std::shared_ptr<ERCodeRule> getERCodeSelector(uint64_t rcode);
+std::shared_ptr<HTTPHeaderRule> getHTTPHeaderSelector(const std::string& header, const std::string& expression);
+std::shared_ptr<HTTPPathRule> getHTTPPathSelector(const std::string& path);
+std::shared_ptr<HTTPPathRegexRule> getHTTPPathRegexSelector(const std::string& expression);
+std::shared_ptr<LuaRule> getLuaSelector(dnsdist::selectors::LuaSelectorFunction function);
+std::shared_ptr<LuaFFIRule> getLuaFFISelector(dnsdist::selectors::LuaSelectorFFIFunction function);
+std::shared_ptr<LuaFFIPerThreadRule> getLuaFFIPerThreadSelector(const std::string& code);
+std::shared_ptr<MaxQPSRule> getMaxQPSSelector(uint32_t qps, std::optional<uint32_t> burst);
+std::shared_ptr<MaxQPSIPRule> getMaxQPSIPSelector(uint32_t qps, std::optional<uint8_t> ipv4Mask, std::optional<uint8_t> ipv6Mask, std::optional<uint32_t> burst, std::optional<uint32_t> expiration, std::optional<uint32_t> cleanupDelay, std::optional<uint32_t> scanFraction, std::optional<uint32_t> shards);
+std::shared_ptr<OpcodeRule> getOpcodeSelector(uint8_t code);
+std::shared_ptr<PayloadSizeRule> getPayloadSizeSelector(const std::string& comparison, uint16_t size);
+std::shared_ptr<PoolAvailableRule> getPoolAvailableSelector(const std::string& pool);
+std::shared_ptr<PoolOutstandingRule> getPoolOutstandingSelector(const std::string& pool, uint64_t maxOutstanding);
+std::shared_ptr<ProbaRule> getProbaSelector(double probability);
+std::shared_ptr<ProxyProtocolValueRule> getProxyProtocolValueSelector(uint8_t optionType, std::optional<std::string> optionValue);
+std::shared_ptr<QNameLabelsCountRule> getQNameLabelsCountSelector(uint16_t minLabelsCount, uint16_t maxLabelsCount);
+std::shared_ptr<QNameWireLengthRule> getQNameWireLengthSelector(uint16_t min, uint16_t max);
+std::shared_ptr<RCodeRule> getRCodeSelector(uint64_t rcode);
+std::shared_ptr<RDRule> getRDSelector();
+std::shared_ptr<RE2Rule> getRE2Selector(const std::string& expression);
+std::shared_ptr<RecordsCountRule> getRecordsCountSelector(uint8_t section, uint16_t minimum, uint16_t maximum);
+std::shared_ptr<RecordsTypeCountRule> getRecordsTypeCountSelector(uint8_t section, uint16_t recordType, uint16_t minimum, uint16_t maximum);
+std::shared_ptr<RegexRule> getRegexSelector(const std::string& expression);
+std::shared_ptr<SNIRule> getSNISelector(const std::string& serverName);
+std::shared_ptr<TagRule> getTagSelector(const std::string& tag, std::optional<std::string> value);
+std::shared_ptr<TCPRule> getTCPSelector(bool tcp);
+std::shared_ptr<TrailingDataRule> getTrailingDataSelector();