From: Remi Gacogne Date: Tue, 24 Dec 2024 15:17:37 +0000 (+0100) Subject: dnsdist: Generate C++ factory and Lua bindings code from YAML definitions X-Git-Tag: dnsdist-2.0.0-alpha1~160^2~31 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=42ae11cfdf8031f885644539050119988e903a91;p=thirdparty%2Fpdns.git dnsdist: Generate C++ factory and Lua bindings code from YAML definitions --- diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index cefe0b021d..f7ca43fab0 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -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 index 0000000000..7c1f5a4855 --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-actions-factory-generated.cc @@ -0,0 +1,101 @@ +// !! This file has been generated by dnsdist-rules-generator.py, do not edit by hand!! +std::shared_ptr getAllowAction() +{ + return std::shared_ptr(new AllowAction()); +} +std::shared_ptr getDelayAction(uint32_t msec) +{ + return std::shared_ptr(new DelayAction(msec)); +} +std::shared_ptr getDropAction() +{ + return std::shared_ptr(new DropAction()); +} +std::shared_ptr getSetEDNSOptionAction(uint32_t code, const std::string& data) +{ + return std::shared_ptr(new SetEDNSOptionAction(code, data)); +} +std::shared_ptr getLogAction(const std::string& fileName, bool binary, bool append, bool buffered, bool verboseOnly, bool includeTimestamp) +{ + return std::shared_ptr(new LogAction(fileName, binary, append, buffered, verboseOnly, includeTimestamp)); +} +std::shared_ptr getLuaAction(dnsdist::actions::LuaActionFunction function) +{ + return std::shared_ptr(new LuaAction(function)); +} +std::shared_ptr getLuaFFIAction(dnsdist::actions::LuaActionFFIFunction function) +{ + return std::shared_ptr(new LuaFFIAction(function)); +} +std::shared_ptr getLuaFFIPerThreadAction(const std::string& code) +{ + return std::shared_ptr(new LuaFFIPerThreadAction(code)); +} +std::shared_ptr getNoneAction() +{ + return std::shared_ptr(new NoneAction()); +} +std::shared_ptr getPoolAction(const std::string& poolName, bool stopProcessing) +{ + return std::shared_ptr(new PoolAction(poolName, stopProcessing)); +} +std::shared_ptr getQPSAction(uint32_t limit) +{ + return std::shared_ptr(new QPSAction(limit)); +} +std::shared_ptr getQPSPoolAction(uint32_t limit, const std::string& poolName, bool stopProcessing) +{ + return std::shared_ptr(new QPSPoolAction(limit, poolName, stopProcessing)); +} +std::shared_ptr getSetAdditionalProxyProtocolValueAction(uint8_t proxyType, const std::string& value) +{ + return std::shared_ptr(new SetAdditionalProxyProtocolValueAction(proxyType, value)); +} +std::shared_ptr getSetDisableECSAction() +{ + return std::shared_ptr(new SetDisableECSAction()); +} +std::shared_ptr getSetDisableValidationAction() +{ + return std::shared_ptr(new SetDisableValidationAction()); +} +std::shared_ptr getSetECSOverrideAction(bool overrideExisting) +{ + return std::shared_ptr(new SetECSOverrideAction(overrideExisting)); +} +std::shared_ptr getSetECSPrefixLengthAction(uint16_t ipv4, uint16_t ipv6) +{ + return std::shared_ptr(new SetECSPrefixLengthAction(ipv4, ipv6)); +} +std::shared_ptr getSetExtendedDNSErrorAction(uint16_t infoCode, const std::string& extraText) +{ + return std::shared_ptr(new SetExtendedDNSErrorAction(infoCode, extraText)); +} +std::shared_ptr getSetMacAddrAction(uint32_t code) +{ + return std::shared_ptr(new SetMacAddrAction(code)); +} +std::shared_ptr getSetNoRecurseAction() +{ + return std::shared_ptr(new SetNoRecurseAction()); +} +std::shared_ptr getSetSkipCacheAction() +{ + return std::shared_ptr(new SetSkipCacheAction()); +} +std::shared_ptr getSetTagAction(const std::string& tag, const std::string& value) +{ + return std::shared_ptr(new SetTagAction(tag, value)); +} +std::shared_ptr getSetTempFailureCacheTTLAction(uint32_t maxTTL) +{ + return std::shared_ptr(new SetTempFailureCacheTTLAction(maxTTL)); +} +std::shared_ptr getSNMPTrapAction(const std::string& reason) +{ + return std::shared_ptr(new SNMPTrapAction(reason)); +} +std::shared_ptr getTCAction() +{ + return std::shared_ptr(new TCAction()); +} diff --git a/pdns/dnsdistdist/dnsdist-actions-factory-generated.hh b/pdns/dnsdistdist/dnsdist-actions-factory-generated.hh new file mode 100644 index 0000000000..fb18c7b78d --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-actions-factory-generated.hh @@ -0,0 +1,26 @@ +// !! This file has been generated by dnsdist-rules-generator.py, do not edit by hand!! +std::shared_ptr getAllowAction(); +std::shared_ptr getDelayAction(uint32_t msec); +std::shared_ptr getDropAction(); +std::shared_ptr getSetEDNSOptionAction(uint32_t code, const std::string& data); +std::shared_ptr getLogAction(const std::string& fileName, bool binary, bool append, bool buffered, bool verboseOnly, bool includeTimestamp); +std::shared_ptr getLuaAction(dnsdist::actions::LuaActionFunction function); +std::shared_ptr getLuaFFIAction(dnsdist::actions::LuaActionFFIFunction function); +std::shared_ptr getLuaFFIPerThreadAction(const std::string& code); +std::shared_ptr getNoneAction(); +std::shared_ptr getPoolAction(const std::string& poolName, bool stopProcessing); +std::shared_ptr getQPSAction(uint32_t limit); +std::shared_ptr getQPSPoolAction(uint32_t limit, const std::string& poolName, bool stopProcessing); +std::shared_ptr getSetAdditionalProxyProtocolValueAction(uint8_t proxyType, const std::string& value); +std::shared_ptr getSetDisableECSAction(); +std::shared_ptr getSetDisableValidationAction(); +std::shared_ptr getSetECSOverrideAction(bool overrideExisting); +std::shared_ptr getSetECSPrefixLengthAction(uint16_t ipv4, uint16_t ipv6); +std::shared_ptr getSetExtendedDNSErrorAction(uint16_t infoCode, const std::string& extraText); +std::shared_ptr getSetMacAddrAction(uint32_t code); +std::shared_ptr getSetNoRecurseAction(); +std::shared_ptr getSetSkipCacheAction(); +std::shared_ptr getSetTagAction(const std::string& tag, const std::string& value); +std::shared_ptr getSetTempFailureCacheTTLAction(uint32_t maxTTL); +std::shared_ptr getSNMPTrapAction(const std::string& reason); +std::shared_ptr getTCAction(); diff --git a/pdns/dnsdistdist/dnsdist-lua-actions-generated.cc b/pdns/dnsdistdist/dnsdist-lua-actions-generated.cc new file mode 100644 index 0000000000..512391972c --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-lua-actions-generated.cc @@ -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 fileName, boost::optional binary, boost::optional append, boost::optional buffered, boost::optional verboseOnly, boost::optional 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 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 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 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 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 index 0000000000..bc5a13ba7c --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-lua-response-actions-generated.cc @@ -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 fileName, boost::optional append, boost::optional buffered, boost::optional verboseOnly, boost::optional 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 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 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 index 0000000000..d16d9050d4 --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-lua-selectors-generated.cc @@ -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(dnsdist::selectors::getAllSelector()); +}); +luaCtx.writeFunction("DNSSECRule", []() { + return std::shared_ptr(dnsdist::selectors::getDNSSECSelector()); +}); +luaCtx.writeFunction("DSTPortRule", [](uint16_t port) { + return std::shared_ptr(dnsdist::selectors::getDSTPortSelector(port)); +}); +luaCtx.writeFunction("EDNSOptionRule", [](uint16_t optionCode) { + return std::shared_ptr(dnsdist::selectors::getEDNSOptionSelector(optionCode)); +}); +luaCtx.writeFunction("EDNSVersionRule", [](uint8_t version) { + return std::shared_ptr(dnsdist::selectors::getEDNSVersionSelector(version)); +}); +luaCtx.writeFunction("ERCodeRule", [](uint64_t rcode) { + return std::shared_ptr(dnsdist::selectors::getERCodeSelector(rcode)); +}); +luaCtx.writeFunction("HTTPHeaderRule", [](std::string header, std::string expression) { + return std::shared_ptr(dnsdist::selectors::getHTTPHeaderSelector(header, expression)); +}); +luaCtx.writeFunction("HTTPPathRule", [](std::string path) { + return std::shared_ptr(dnsdist::selectors::getHTTPPathSelector(path)); +}); +luaCtx.writeFunction("HTTPPathRegexRule", [](std::string expression) { + return std::shared_ptr(dnsdist::selectors::getHTTPPathRegexSelector(expression)); +}); +luaCtx.writeFunction("LuaRule", [](dnsdist::selectors::LuaSelectorFunction function) { + return std::shared_ptr(dnsdist::selectors::getLuaSelector(function)); +}); +luaCtx.writeFunction("LuaFFIRule", [](dnsdist::selectors::LuaSelectorFFIFunction function) { + return std::shared_ptr(dnsdist::selectors::getLuaFFISelector(function)); +}); +luaCtx.writeFunction("LuaFFIPerThreadRule", [](std::string code) { + return std::shared_ptr(dnsdist::selectors::getLuaFFIPerThreadSelector(code)); +}); +luaCtx.writeFunction("MaxQPSRule", [](uint32_t qps, boost::optional burst) { + return std::shared_ptr(dnsdist::selectors::getMaxQPSSelector(qps, boostToStandardOptional(burst))); +}); +luaCtx.writeFunction("MaxQPSIPRule", [](uint32_t qps, boost::optional ipv4Mask, boost::optional ipv6Mask, boost::optional burst, boost::optional expiration, boost::optional cleanupDelay, boost::optional scanFraction, boost::optional shards) { + return std::shared_ptr(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(dnsdist::selectors::getOpcodeSelector(code)); +}); +luaCtx.writeFunction("PayloadSizeRule", [](std::string comparison, uint16_t size) { + return std::shared_ptr(dnsdist::selectors::getPayloadSizeSelector(comparison, size)); +}); +luaCtx.writeFunction("PoolAvailableRule", [](std::string pool) { + return std::shared_ptr(dnsdist::selectors::getPoolAvailableSelector(pool)); +}); +luaCtx.writeFunction("PoolOutstandingRule", [](std::string pool, uint64_t maxOutstanding) { + return std::shared_ptr(dnsdist::selectors::getPoolOutstandingSelector(pool, maxOutstanding)); +}); +luaCtx.writeFunction("ProbaRule", [](double probability) { + return std::shared_ptr(dnsdist::selectors::getProbaSelector(probability)); +}); +luaCtx.writeFunction("ProxyProtocolValueRule", [](uint8_t optionType, boost::optional optionValue) { + return std::shared_ptr(dnsdist::selectors::getProxyProtocolValueSelector(optionType, boostToStandardOptional(optionValue))); +}); +luaCtx.writeFunction("QNameLabelsCountRule", [](uint16_t minLabelsCount, uint16_t maxLabelsCount) { + return std::shared_ptr(dnsdist::selectors::getQNameLabelsCountSelector(minLabelsCount, maxLabelsCount)); +}); +luaCtx.writeFunction("QNameWireLengthRule", [](uint16_t min, uint16_t max) { + return std::shared_ptr(dnsdist::selectors::getQNameWireLengthSelector(min, max)); +}); +luaCtx.writeFunction("RCodeRule", [](uint64_t rcode) { + return std::shared_ptr(dnsdist::selectors::getRCodeSelector(rcode)); +}); +luaCtx.writeFunction("RDRule", []() { + return std::shared_ptr(dnsdist::selectors::getRDSelector()); +}); +luaCtx.writeFunction("RE2Rule", [](std::string expression) { + return std::shared_ptr(dnsdist::selectors::getRE2Selector(expression)); +}); +luaCtx.writeFunction("RecordsCountRule", [](uint8_t section, uint16_t minimum, uint16_t maximum) { + return std::shared_ptr(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(dnsdist::selectors::getRecordsTypeCountSelector(section, recordType, minimum, maximum)); +}); +luaCtx.writeFunction("RegexRule", [](std::string expression) { + return std::shared_ptr(dnsdist::selectors::getRegexSelector(expression)); +}); +luaCtx.writeFunction("SNIRule", [](std::string serverName) { + return std::shared_ptr(dnsdist::selectors::getSNISelector(serverName)); +}); +luaCtx.writeFunction("TagRule", [](std::string tag, boost::optional value) { + return std::shared_ptr(dnsdist::selectors::getTagSelector(tag, boostToStandardOptional(value))); +}); +luaCtx.writeFunction("TCPRule", [](bool tcp) { + return std::shared_ptr(dnsdist::selectors::getTCPSelector(tcp)); +}); +luaCtx.writeFunction("TrailingDataRule", []() { + return std::shared_ptr(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 index 0000000000..3066ffb12d --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-response-actions-factory-generated.cc @@ -0,0 +1,53 @@ +// !! This file has been generated by dnsdist-rules-generator.py, do not edit by hand!! +std::shared_ptr getAllowResponseAction() +{ + return std::shared_ptr(new AllowResponseAction()); +} +std::shared_ptr getDelayResponseAction(uint32_t msec) +{ + return std::shared_ptr(new DelayResponseAction(msec)); +} +std::shared_ptr getDropResponseAction() +{ + return std::shared_ptr(new DropResponseAction()); +} +std::shared_ptr getLogResponseAction(const std::string& fileName, bool append, bool buffered, bool verboseOnly, bool includeTimestamp) +{ + return std::shared_ptr(new LogResponseAction(fileName, append, buffered, verboseOnly, includeTimestamp)); +} +std::shared_ptr getLuaResponseAction(dnsdist::actions::LuaResponseActionFunction function) +{ + return std::shared_ptr(new LuaResponseAction(function)); +} +std::shared_ptr getLuaFFIResponseAction(dnsdist::actions::LuaResponseActionFFIFunction function) +{ + return std::shared_ptr(new LuaFFIResponseAction(function)); +} +std::shared_ptr getLuaFFIPerThreadResponseAction(const std::string& code) +{ + return std::shared_ptr(new LuaFFIPerThreadResponseAction(code)); +} +std::shared_ptr getSetExtendedDNSErrorResponseAction(uint16_t infoCode, const std::string& extraText) +{ + return std::shared_ptr(new SetExtendedDNSErrorResponseAction(infoCode, extraText)); +} +std::shared_ptr getSetReducedTTLResponseAction(uint8_t percentage) +{ + return std::shared_ptr(new SetReducedTTLResponseAction(percentage)); +} +std::shared_ptr getSetSkipCacheResponseAction() +{ + return std::shared_ptr(new SetSkipCacheResponseAction()); +} +std::shared_ptr getSetTagResponseAction(const std::string& tag, const std::string& value) +{ + return std::shared_ptr(new SetTagResponseAction(tag, value)); +} +std::shared_ptr getSNMPTrapResponseAction(const std::string& reason) +{ + return std::shared_ptr(new SNMPTrapResponseAction(reason)); +} +std::shared_ptr getTCResponseAction() +{ + return std::shared_ptr(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 index 0000000000..839dbaf86b --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-response-actions-factory-generated.hh @@ -0,0 +1,14 @@ +// !! This file has been generated by dnsdist-rules-generator.py, do not edit by hand!! +std::shared_ptr getAllowResponseAction(); +std::shared_ptr getDelayResponseAction(uint32_t msec); +std::shared_ptr getDropResponseAction(); +std::shared_ptr getLogResponseAction(const std::string& fileName, bool append, bool buffered, bool verboseOnly, bool includeTimestamp); +std::shared_ptr getLuaResponseAction(dnsdist::actions::LuaResponseActionFunction function); +std::shared_ptr getLuaFFIResponseAction(dnsdist::actions::LuaResponseActionFFIFunction function); +std::shared_ptr getLuaFFIPerThreadResponseAction(const std::string& code); +std::shared_ptr getSetExtendedDNSErrorResponseAction(uint16_t infoCode, const std::string& extraText); +std::shared_ptr getSetReducedTTLResponseAction(uint8_t percentage); +std::shared_ptr getSetSkipCacheResponseAction(); +std::shared_ptr getSetTagResponseAction(const std::string& tag, const std::string& value); +std::shared_ptr getSNMPTrapResponseAction(const std::string& reason); +std::shared_ptr getTCResponseAction(); diff --git a/pdns/dnsdistdist/dnsdist-rules-generator.py b/pdns/dnsdistdist/dnsdist-rules-generator.py new file mode 100644 index 0000000000..cb6c0d73f8 --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-rules-generator.py @@ -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 get{name}{suffix}(' + if 'parameters' in action: + output += get_cpp_parameters_definition(action['parameters'], False) + output += ')\n{\n' + output += f' return std::shared_ptr(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(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 index 0000000000..224ff58f42 --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-selectors-factory-generated.cc @@ -0,0 +1,129 @@ +// !! This file has been generated by dnsdist-rules-generator.py, do not edit by hand!! +std::shared_ptr getAllSelector() +{ + return std::make_shared(); +} +std::shared_ptr getDNSSECSelector() +{ + return std::make_shared(); +} +std::shared_ptr getDSTPortSelector(uint16_t port) +{ + return std::make_shared(port); +} +std::shared_ptr getEDNSOptionSelector(uint16_t optionCode) +{ + return std::make_shared(optionCode); +} +std::shared_ptr getEDNSVersionSelector(uint8_t version) +{ + return std::make_shared(version); +} +std::shared_ptr getERCodeSelector(uint64_t rcode) +{ + return std::make_shared(rcode); +} +std::shared_ptr getHTTPHeaderSelector(const std::string& header, const std::string& expression) +{ + return std::make_shared(header, expression); +} +std::shared_ptr getHTTPPathSelector(const std::string& path) +{ + return std::make_shared(path); +} +std::shared_ptr getHTTPPathRegexSelector(const std::string& expression) +{ + return std::make_shared(expression); +} +std::shared_ptr getLuaSelector(dnsdist::selectors::LuaSelectorFunction function) +{ + return std::make_shared(function); +} +std::shared_ptr getLuaFFISelector(dnsdist::selectors::LuaSelectorFFIFunction function) +{ + return std::make_shared(function); +} +std::shared_ptr getLuaFFIPerThreadSelector(const std::string& code) +{ + return std::make_shared(code); +} +std::shared_ptr getMaxQPSSelector(uint32_t qps, std::optional burst) +{ + return std::make_shared(qps, burst ? *burst : 0); +} +std::shared_ptr getMaxQPSIPSelector(uint32_t qps, std::optional ipv4Mask, std::optional ipv6Mask, std::optional burst, std::optional expiration, std::optional cleanupDelay, std::optional scanFraction, std::optional shards) +{ + return std::make_shared(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 getOpcodeSelector(uint8_t code) +{ + return std::make_shared(code); +} +std::shared_ptr getPayloadSizeSelector(const std::string& comparison, uint16_t size) +{ + return std::make_shared(comparison, size); +} +std::shared_ptr getPoolAvailableSelector(const std::string& pool) +{ + return std::make_shared(pool); +} +std::shared_ptr getPoolOutstandingSelector(const std::string& pool, uint64_t maxOutstanding) +{ + return std::make_shared(pool, maxOutstanding); +} +std::shared_ptr getProbaSelector(double probability) +{ + return std::make_shared(probability); +} +std::shared_ptr getProxyProtocolValueSelector(uint8_t optionType, std::optional optionValue) +{ + return std::make_shared(optionType, optionValue ? *optionValue : ""); +} +std::shared_ptr getQNameLabelsCountSelector(uint16_t minLabelsCount, uint16_t maxLabelsCount) +{ + return std::make_shared(minLabelsCount, maxLabelsCount); +} +std::shared_ptr getQNameWireLengthSelector(uint16_t min, uint16_t max) +{ + return std::make_shared(min, max); +} +std::shared_ptr getRCodeSelector(uint64_t rcode) +{ + return std::make_shared(rcode); +} +std::shared_ptr getRDSelector() +{ + return std::make_shared(); +} +std::shared_ptr getRE2Selector(const std::string& expression) +{ + return std::make_shared(expression); +} +std::shared_ptr getRecordsCountSelector(uint8_t section, uint16_t minimum, uint16_t maximum) +{ + return std::make_shared(section, minimum, maximum); +} +std::shared_ptr getRecordsTypeCountSelector(uint8_t section, uint16_t recordType, uint16_t minimum, uint16_t maximum) +{ + return std::make_shared(section, recordType, minimum, maximum); +} +std::shared_ptr getRegexSelector(const std::string& expression) +{ + return std::make_shared(expression); +} +std::shared_ptr getSNISelector(const std::string& serverName) +{ + return std::make_shared(serverName); +} +std::shared_ptr getTagSelector(const std::string& tag, std::optional value) +{ + return std::make_shared(tag, value ? *value : ""); +} +std::shared_ptr getTCPSelector(bool tcp) +{ + return std::make_shared(tcp); +} +std::shared_ptr getTrailingDataSelector() +{ + return std::make_shared(); +} diff --git a/pdns/dnsdistdist/dnsdist-selectors-factory-generated.hh b/pdns/dnsdistdist/dnsdist-selectors-factory-generated.hh new file mode 100644 index 0000000000..fe48132d47 --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-selectors-factory-generated.hh @@ -0,0 +1,33 @@ +// !! This file has been generated by dnsdist-rules-generator.py, do not edit by hand!! +std::shared_ptr getAllSelector(); +std::shared_ptr getDNSSECSelector(); +std::shared_ptr getDSTPortSelector(uint16_t port); +std::shared_ptr getEDNSOptionSelector(uint16_t optionCode); +std::shared_ptr getEDNSVersionSelector(uint8_t version); +std::shared_ptr getERCodeSelector(uint64_t rcode); +std::shared_ptr getHTTPHeaderSelector(const std::string& header, const std::string& expression); +std::shared_ptr getHTTPPathSelector(const std::string& path); +std::shared_ptr getHTTPPathRegexSelector(const std::string& expression); +std::shared_ptr getLuaSelector(dnsdist::selectors::LuaSelectorFunction function); +std::shared_ptr getLuaFFISelector(dnsdist::selectors::LuaSelectorFFIFunction function); +std::shared_ptr getLuaFFIPerThreadSelector(const std::string& code); +std::shared_ptr getMaxQPSSelector(uint32_t qps, std::optional burst); +std::shared_ptr getMaxQPSIPSelector(uint32_t qps, std::optional ipv4Mask, std::optional ipv6Mask, std::optional burst, std::optional expiration, std::optional cleanupDelay, std::optional scanFraction, std::optional shards); +std::shared_ptr getOpcodeSelector(uint8_t code); +std::shared_ptr getPayloadSizeSelector(const std::string& comparison, uint16_t size); +std::shared_ptr getPoolAvailableSelector(const std::string& pool); +std::shared_ptr getPoolOutstandingSelector(const std::string& pool, uint64_t maxOutstanding); +std::shared_ptr getProbaSelector(double probability); +std::shared_ptr getProxyProtocolValueSelector(uint8_t optionType, std::optional optionValue); +std::shared_ptr getQNameLabelsCountSelector(uint16_t minLabelsCount, uint16_t maxLabelsCount); +std::shared_ptr getQNameWireLengthSelector(uint16_t min, uint16_t max); +std::shared_ptr getRCodeSelector(uint64_t rcode); +std::shared_ptr getRDSelector(); +std::shared_ptr getRE2Selector(const std::string& expression); +std::shared_ptr getRecordsCountSelector(uint8_t section, uint16_t minimum, uint16_t maximum); +std::shared_ptr getRecordsTypeCountSelector(uint8_t section, uint16_t recordType, uint16_t minimum, uint16_t maximum); +std::shared_ptr getRegexSelector(const std::string& expression); +std::shared_ptr getSNISelector(const std::string& serverName); +std::shared_ptr getTagSelector(const std::string& tag, std::optional value); +std::shared_ptr getTCPSelector(bool tcp); +std::shared_ptr getTrailingDataSelector();