Travaille
tribool
trustanchor
+trustanchorfile
trusteer
trx
trxid
zonemetadata
zonename
zoneparser
+zonetocaches
zonetransfer
Zonneveld
zsk
zone->clear();
}
}
+ lci.rpzRaw.emplace_back(RPZRaw{primaries, zoneName, options});
}
catch (const std::exception& e) {
SLOG(g_log << Logger::Error << "Problem configuring 'rpzPrimary': " << e.what() << endl,
lci.dfe.addZone(std::move(zone));
SLOG(g_log << Logger::Warning << "Done loading RPZ from file '" << filename << "'" << endl,
log->info(Logr::Info, "Done loading RPZ from file"));
+ lci.rpzRaw.emplace_back(RPZRaw{{}, filename, options});
}
catch (const std::exception& e) {
SLOG(g_log << Logger::Error << "Unable to load RPZ zone from '" << filename << "': " << e.what() << endl,
*/
#pragma once
#include <set>
+#include <boost/variant.hpp>
#include "sholder.hh"
#include "sortlist.hh"
using ProxyMapping = NetmaskTree<ProxyByTableValue, Netmask>;
+using rpzOptions_t = std::unordered_map<std::string, boost::variant<bool, uint32_t, std::string, std::vector<std::pair<int, std::string>>>>;
+
+struct RPZRaw
+{
+ std::vector<ComboAddress> addresses;
+ std::string name;
+ boost::optional<rpzOptions_t> options;
+};
+
class LuaConfigItems
{
public:
LuaConfigItems();
SortList sortlist;
DNSFilterEngine dfe;
+ vector<RPZRaw> rpzRaw;
TrustAnchorFileInfo trustAnchorFileInfo; // Used to update the Trust Anchors from file periodically
map<DNSName, dsset_t> dsAnchors;
map<DNSName, std::string> negAnchors;
pdns::rust::settings::rec::Recursorsettings settings;
pdns::settings::rec::oldStyleSettingsToBridgeStruct(settings);
luaConfigDelayedThreads delayedLuaThreads;
+ ProxyMapping proxyMapping;
try {
- ProxyMapping proxyMapping;
loadRecursorLuaConfig(::arg()["lua-config-file"], delayedLuaThreads, proxyMapping);
}
catch (PDNSException& e) {
startupLog->error(Logr::Error, e.reason, "Cannot load Lua configuration"));
}
auto luaConfig = g_luaconfs.getLocal();
- settings.dnssec.trustanchorfile = luaConfig->trustAnchorFileInfo.fname;
- settings.dnssec.trustanchorfile_interval = luaConfig->trustAnchorFileInfo.interval;
- for (const auto& anchors : luaConfig->dsAnchors) {
- rust::Vec<rust::String> dsRecords;
- for (const auto& dsRecord : anchors.second) {
- dsRecords.emplace_back(dsRecord.getZoneRepresentation());
- }
- pdns::rust::settings::rec::TrustAnchor trustAnchor{anchors.first.toString(), dsRecords};
- settings.dnssec.trustanchors.emplace_back(trustAnchor);
- }
- for (const auto& anchors : luaConfig->negAnchors) {
- pdns::rust::settings::rec::NegativeTrustAnchor negtrustAnchor{anchors.first.toString(), anchors.second};
- settings.dnssec.negative_trustanchors.emplace_back(negtrustAnchor);
- }
-
+ pdns::settings::rec::fromLuaConfigToBridgeStruct(luaConfig, proxyMapping, settings);
auto yaml = settings.to_yaml_string();
cout << yaml << endl;
}
#include <string>
#include "rust/cxx.h"
#include "rust/lib.rs.h"
+#include "sholder.hh"
#include "logging.hh"
+#include "rec-lua-conf.hh"
namespace pdns::settings::rec
{
void readYamlAllowNotifyForFile(const std::string& filename, ::rust::Vec<::rust::String>& vec, Logr::log_t log);
void setArgsForZoneRelatedSettings(pdns::rust::settings::rec::Recursorsettings& settings);
void setArgsForACLRelatedSettings(pdns::rust::settings::rec::Recursorsettings& settings);
+void fromLuaConfigToBridgeStruct(LocalStateHolder<LuaConfigItems>& luaConfig, const ProxyMapping& proxyMapping, pdns::rust::settings::rec::Recursorsettings& settings);
}
#include "cxxsettings-private.hh"
#include "logger.hh"
#include "logging.hh"
+#include "rec-lua-conf.hh"
::rust::Vec<::rust::String> pdns::settings::rec::getStrings(const std::string& name)
{
::rust::String section;
::rust::String fieldname;
::rust::String type_name;
- pdns::rust::settings::rec::Value rustvalue = {false, 0, 0.0, "", {}, {}, {}, {}, {}};
+ pdns::rust::settings::rec::Value rustvalue = {false, 0, 0.0, "", {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}};
if (pdns::settings::rec::oldKVToBridgeStruct(var, val, section, fieldname, type_name, rustvalue)) {
auto overriding = !mainFile && !incremental && !simpleRustType(type_name);
auto [existing, inserted] = map.emplace(std::pair{std::pair{section, fieldname}, pdns::rust::settings::rec::OldStyle{section, fieldname, var, std::move(type_name), rustvalue, overriding}});
::rust::String section;
::rust::String fieldname;
::rust::String type_name;
- pdns::rust::settings::rec::Value rustvalue{false, 0, 0.0, "", {}, {}, {}, {}, {}};
+ pdns::rust::settings::rec::Value rustvalue{false, 0, 0.0, "", {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}};
string name = var;
string val = arg().getDefault(var);
if (pdns::settings::rec::oldKVToBridgeStruct(name, val, section, fieldname, type_name, rustvalue)) {
map.emplace(std::pair{std::pair{section, fieldname}, pdns::rust::settings::rec::OldStyle{section, fieldname, name, std::move(type_name), std::move(rustvalue), false}});
}
}
+
+ // Should be generated
+ auto def = [&](const string& section, const string& name, const string& type) {
+ pdns::rust::settings::rec::Value rustvalue{.vec_trustanchor_val = {}, .vec_negativetrustanchor_val = {}, .string_val = "", .u64_val = 24, .vec_protobufserver_val = {}};
+ map.emplace(std::pair{std::pair{section, name}, pdns::rust::settings::rec::OldStyle{section, name, name, type, rustvalue, false}});
+ };
+ def("dnssec", "trustanchors", "Vec<TrustAnchor>");
+ def("dnssec", "negative_trustanchors", "Vec<NegativeTrustAnchor>");
+ def("dnssec", "trustanchorfile", "String");
+ def("dnssec", "trustanchorfile_interval", "u64");
+ def("logging", "protobuf_servers", "Vec<ProtobufServer>");
+ def("logging", "outgoing_protobuf_servers", "Vec<ProtobufServer>");
+ def("logging", "dnstap_framestream_servers", "Vec<DNSTapFrameStreamServer>");
+ def("logging", "dnstap_nod_framestream_servers", "Vec<DNSTapNODFrameStreamServer>");
+ def("recursor", "rpzs", "Vec<RPZ>");
+ def("recursor", "sortlists", "Vec<SortList>");
+ def("recordcache", "zonetocaches", "Vec<ZoneToCache>");
+ def("recursor", "allowed_additional_qtypes", "Vec<AllowedAdditionalQType>");
+ def("incoming", "proxymappings", "Vec<ProxyMapping>");
+ // End of should be generated XXX
+
// Convert the map to a vector, as CXX does not have any dictionary like support.
::rust::Vec<pdns::rust::settings::rec::OldStyle> vec;
vec.reserve(map.size());
}
return res;
}
+
+namespace
+{
+void fromLuaToProtobufServerStruct(const ProtobufExportConfig& pbConfig, pdns::rust::settings::rec::ProtobufServer& pbServer)
+{
+ for (const auto& server : pbConfig.servers) {
+ pbServer.servers.emplace_back(server.toStringWithPort());
+ }
+ pbServer.timeout = pbConfig.timeout;
+ pbServer.maxQueuedEntries = pbConfig.maxQueuedEntries;
+ pbServer.reconnectWaitTime = pbConfig.reconnectWaitTime;
+ pbServer.taggedOnly = pbConfig.taggedOnly;
+ pbServer.asyncConnect = pbConfig.asyncConnect;
+ pbServer.logQueries = pbConfig.logQueries;
+ pbServer.logResponses = pbConfig.logResponses;
+ for (const auto num : pbConfig.exportTypes) {
+ pbServer.exportTypes.emplace_back(QType(num).toString());
+ }
+ pbServer.logMappedFrom = pbConfig.logMappedFrom;
+}
+
+void fromLuaConfigToTAInfo(LocalStateHolder<LuaConfigItems>& luaConfig, pdns::rust::settings::rec::Dnssec& dnssec)
+{
+ dnssec.trustanchorfile = luaConfig->trustAnchorFileInfo.fname;
+ dnssec.trustanchorfile_interval = luaConfig->trustAnchorFileInfo.interval;
+ for (const auto& anchors : luaConfig->dsAnchors) {
+ ::rust::Vec<::rust::String> dsRecords;
+ for (const auto& dsRecord : anchors.second) {
+ dsRecords.emplace_back(dsRecord.getZoneRepresentation());
+ }
+ pdns::rust::settings::rec::TrustAnchor trustAnchor{anchors.first.toString(), dsRecords};
+ dnssec.trustanchors.emplace_back(trustAnchor);
+ }
+ for (const auto& anchors : luaConfig->negAnchors) {
+ pdns::rust::settings::rec::NegativeTrustAnchor negtrustAnchor{anchors.first.toString(), anchors.second};
+ dnssec.negative_trustanchors.emplace_back(negtrustAnchor);
+ }
+}
+
+template <typename T>
+void setIfAvailable(const rpzOptions_t& table, T& var, const std::string& name)
+{
+ if (table.count(name) != 0) {
+ var = boost::get<T>(table.at(name));
+ }
+}
+
+void setIfAvailable(const rpzOptions_t& table, rust::string& var, const std::string& name)
+{
+ if (table.count(name) != 0) {
+ var = boost::get<std::string>(table.at(name));
+ }
+}
+
+void setIfAvailable(const rpzOptions_t& table, pdns::rust::settings::rec::TSIGTriplet& var, const std::string& name)
+{
+ if (table.count(name) != 0) {
+ var.name = boost::get<std::string>(table.at("tsigname"));
+ var.algo = boost::get<std::string>(table.at("tsigalgo"));
+ var.secret = boost::get<std::string>(table.at("tsigsecret"));
+ }
+}
+void fromLuaConfigToRPZ(const vector<RPZRaw>& rpzs, pdns::rust::settings::rec::Recursor& rec)
+{
+ for (const auto& rpz : rpzs) {
+ pdns::rust::settings::rec::RPZ rustrpz{
+ .defpolOverrideLocalData = true,
+ .defttl = std::numeric_limits<uint32_t>::max(),
+ .extendedErrorCode = 0,
+ .includeSOA = false,
+ .ignoreDuplicates = false,
+ .maxTTL = std::numeric_limits<uint32_t>::max(),
+ .overridesGettag = true,
+ .zoneSizeHint = 0,
+ .refresh = 0,
+ .maxReceivedMBytes = 0,
+ .axfrTimeout = 20};
+
+ for (const auto& address : rpz.addresses) {
+ rustrpz.addresses.emplace_back(address.toStringWithPort());
+ }
+ rustrpz.name = rpz.name;
+ if (rpz.options) {
+ setIfAvailable(*rpz.options, rustrpz.defcontent, "defcontent");
+ setIfAvailable(*rpz.options, rustrpz.defpol, "defpol");
+ setIfAvailable(*rpz.options, rustrpz.defpolOverrideLocalData, "defpolOverrideLocalData");
+ setIfAvailable(*rpz.options, rustrpz.defttl, "defttl");
+ setIfAvailable(*rpz.options, rustrpz.extendedErrorCode, "extendedErrorCode");
+ setIfAvailable(*rpz.options, rustrpz.extendedErrorExtra, "extendedErrorExtra");
+ setIfAvailable(*rpz.options, rustrpz.includeSOA, "includeSOA");
+ setIfAvailable(*rpz.options, rustrpz.ignoreDuplicates, "ignoreDuplicates");
+ setIfAvailable(*rpz.options, rustrpz.maxTTL, "maxTTL");
+ setIfAvailable(*rpz.options, rustrpz.policyName, "policyName");
+ if (rpz.options->count("tags") != 0) {
+ const auto& tags = boost::get<vector<std::pair<int, std::string>>>(rpz.options->at("have"));
+ for (const auto& tag : tags) {
+ rustrpz.tags.emplace_back(tag.second);
+ }
+ }
+ setIfAvailable(*rpz.options, rustrpz.overridesGettag, "overridesGettag");
+ setIfAvailable(*rpz.options, rustrpz.zoneSizeHint, "zoneSizeHint");
+ setIfAvailable(*rpz.options, rustrpz.tsig, "tsig");
+ setIfAvailable(*rpz.options, rustrpz.refresh, "refresh");
+ setIfAvailable(*rpz.options, rustrpz.maxReceivedMBytes, "maxReceivedMBytes");
+ setIfAvailable(*rpz.options, rustrpz.localAddress, "localAddress");
+ setIfAvailable(*rpz.options, rustrpz.axfrTimeout, "axfrTimeout");
+ setIfAvailable(*rpz.options, rustrpz.dumpFile, "dumpFile");
+ setIfAvailable(*rpz.options, rustrpz.seedFile, "seedFile");
+ }
+ rec.rpzs.emplace_back(rustrpz);
+ }
+}
+
+string cvt(pdns::ZoneMD::Config cfg)
+{
+ switch (cfg) {
+ case pdns::ZoneMD::Config::Ignore:
+ return "ignore";
+ case pdns::ZoneMD::Config::Validate:
+ return "validate";
+ case pdns::ZoneMD::Config::Require:
+ return "require";
+ }
+}
+
+void fromLuaConfigToZoneToCache(const map<DNSName, RecZoneToCache::Config>& ztcConfigs, pdns::rust::settings::rec::Recordcache& recordcache)
+{
+ for (const auto& [_, iter] : ztcConfigs) {
+ pdns::rust::settings::rec::ZoneToCache ztc;
+ ztc.zone = iter.d_zone;
+ ztc.method = iter.d_method;
+ for (const auto& src : iter.d_sources) {
+ ztc.sources.emplace_back(src);
+ }
+ ztc.timeout = iter.d_timeout;
+ if (!iter.d_tt.name.empty()) {
+ ztc.tsig.name = iter.d_tt.name.toString();
+ ztc.tsig.algo = iter.d_tt.algo.toString();
+ ztc.tsig.secret = iter.d_tt.secret;
+ }
+ ztc.refreshPeriod = iter.d_refreshPeriod;
+ ztc.retryOnErrorPeriod = iter.d_retryOnError;
+ ztc.maxReceivedMBytes = iter.d_maxReceivedBytes;
+ ztc.localAddress = iter.d_local.toStringWithPort();
+ ztc.zonemd = cvt(iter.d_zonemd);
+ ztc.dnssec = cvt(iter.d_dnssec);
+ recordcache.zonetocaches.emplace_back(ztc);
+ }
+}
+string cvt(AdditionalMode mode)
+{
+ switch (mode) {
+ case AdditionalMode::Ignore:
+ return "Ignore";
+ case AdditionalMode::CacheOnly:
+ return "CacheOnly";
+ case AdditionalMode::CacheOnlyRequireAuth:
+ return "CacheOnlyRequireAuth";
+ case AdditionalMode::ResolveImmediately:
+ return "ResolveImmediately";
+ case AdditionalMode::ResolveDeferred:
+ return "ResolveDeferred";
+ }
+}
+
+void fromLuaConfigToAllowAddtionalQTypes(const std::map<QType, std::pair<std::set<QType>, AdditionalMode>>& allowAdditionalQTypes, pdns::rust::settings::rec::Recursor& rec)
+{
+ for (const auto& [qtype, data] : allowAdditionalQTypes) {
+ const auto& [qtypeset, mode] = data;
+ pdns::rust::settings::rec::AllowedAdditionalQType add;
+ add.qtype = qtype.toString();
+ for (const auto& extra : qtypeset) {
+ add.targets.emplace_back(extra.toString());
+ }
+ add.mode = cvt(mode);
+ rec.allowed_additional_qtypes.emplace_back(add);
+ }
+}
+
+void fromLuaConfigToProxyMappings(const ProxyMapping& proxyMapping, pdns::rust::settings::rec::Incoming& incoming)
+{
+ for (const auto& mapping : proxyMapping) {
+ pdns::rust::settings::rec::ProxyMapping pmap;
+ pmap.subnet = mapping.first.toString();
+ pmap.address = mapping.second.address.toString();
+ if (mapping.second.suffixMatchNode) {
+ for (const auto& domain : mapping.second.suffixMatchNode->d_tree.getNodes()) {
+ pmap.domains.emplace_back(domain.toString());
+ }
+ }
+ incoming.proxymappings.emplace_back(pmap);
+ }
+}
+
+void fromLuaConfigToSortList(const SortList& arg, pdns::rust::settings::rec::Recursor& rec)
+{
+ const auto& sortlist = arg.getTree();
+ for (const auto& iter : sortlist) {
+ pdns::rust::settings::rec::SortList rsl;
+ rsl.key = iter.first.toString();
+ const auto& sub = iter.second;
+ // Some extra work to present them ordered in the YAML
+ std::set<int> indexes;
+ std::multimap<int, Netmask> ordered;
+ for (auto& order : sub.d_orders) {
+ indexes.emplace(order.second);
+ ordered.emplace(order.second, order.first);
+ }
+ for (const auto& index : indexes) {
+ const auto& range = ordered.equal_range(index);
+ for (auto subnet = range.first; subnet != range.second; ++subnet) {
+ pdns::rust::settings::rec::SubnetOrder snorder;
+ snorder.order = index;
+ snorder.subnet = subnet->second.toString();
+ rsl.subnets.emplace_back(snorder);
+ }
+ }
+ rec.sortlists.emplace_back(rsl);
+ }
+}
+} // namespace
+
+void pdns::settings::rec::fromLuaConfigToBridgeStruct(LocalStateHolder<LuaConfigItems>& luaConfig, const ProxyMapping& proxyMapping, pdns::rust::settings::rec::Recursorsettings& settings)
+{
+
+ fromLuaConfigToTAInfo(luaConfig, settings.dnssec);
+ if (luaConfig->protobufExportConfig.enabled) {
+ pdns::rust::settings::rec::ProtobufServer pbServer;
+ fromLuaToProtobufServerStruct(luaConfig->protobufExportConfig, pbServer);
+ settings.logging.protobuf_servers.emplace_back(pbServer);
+ }
+ if (luaConfig->outgoingProtobufExportConfig.enabled) {
+ pdns::rust::settings::rec::ProtobufServer pbServer;
+ fromLuaToProtobufServerStruct(luaConfig->outgoingProtobufExportConfig, pbServer);
+ settings.logging.outgoing_protobuf_servers.emplace_back(pbServer);
+ }
+
+ fromLuaConfigToRPZ(luaConfig->rpzRaw, settings.recursor);
+ fromLuaConfigToSortList(luaConfig->sortlist, settings.recursor);
+ fromLuaConfigToZoneToCache(luaConfig->ztcConfigs, settings.recordcache);
+ fromLuaConfigToAllowAddtionalQTypes(luaConfig->allowAdditionalQTypes, settings.recursor);
+ fromLuaConfigToProxyMappings(proxyMapping, settings.incoming);
+}
Bool = auto()
Command = auto()
Double = auto()
+ ListAllowedAdditionalQTypes = auto()
ListAuthZones = auto()
+ ListDNSTapFrameStreamServers = auto()
+ ListDNSTapNODFrameStreamServers = auto()
ListForwardZones = auto()
ListNegativeTrustAnchors = auto()
+ ListProtobufServers = auto()
+ ListProxyMappings = auto()
+ ListRPZs = auto();
ListSocketAddresses = auto()
+ ListSortLists = auto()
ListStrings = auto()
ListSubnets = auto()
ListTrustAnchors = auto()
+ ListZoneToCaches = auto()
String = auto()
Uint64 = auto()
listOfStringTypes = (LType.ListSocketAddresses, LType.ListStrings, LType.ListSubnets)
-listOfStructuredTypes = (LType.ListAuthZones, LType.ListForwardZones, LType.ListTrustAnchors, LType.ListNegativeTrustAnchors)
+listOfStructuredTypes = (LType.ListAuthZones, LType.ListForwardZones, LType.ListTrustAnchors, LType.ListNegativeTrustAnchors,
+ LType.ListProtobufServers, LType.ListDNSTapFrameStreamServers, LType.ListDNSTapNODFrameStreamServers,
+ LType.ListSortLists, LType.ListRPZs, LType.ListZoneToCaches, LType.ListAllowedAdditionalQTypes,
+ LType.ListProxyMappings)
def get_olddoc_typename(typ):
"""Given a type from table.py, return the old-style type name"""
reason: String,
}
-// A struct holding bot a vector of forward zones and a vector o auth zones, used by REST API code
+// A protobuf logging server
+#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
+#[serde(deny_unknown_fields)]
+pub struct ProtobufServer {
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ servers: Vec<String>,
+ #[serde(default = "crate::U64::<2>::value", skip_serializing_if = "crate::U64::<2>::is_equal")]
+ timeout: u64,
+ #[serde(default = "crate::U64::<100>::value", skip_serializing_if = "crate::U64::<100>::is_equal")]
+ maxQueuedEntries: u64,
+ #[serde(default = "crate::U64::<1>::value", skip_serializing_if = "crate::U64::<1>::is_equal")]
+ reconnectWaitTime: u64,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ taggedOnly: bool,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ asyncConnect: bool,
+ #[serde(default = "crate::Bool::<true>::value", skip_serializing_if = "crate::if_true")]
+ logQueries: bool,
+ #[serde(default = "crate::Bool::<true>::value", skip_serializing_if = "crate::if_true")]
+ logResponses: bool,
+ #[serde(default = "crate::def_pb_export_qtypes", skip_serializing_if = "crate::default_value_equal_pb_export_qtypes")]
+ exportTypes: Vec<String>,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ logMappedFrom: bool,
+}
+
+// A dnstap logging server
+#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
+#[serde(deny_unknown_fields)]
+pub struct DNSTapFrameStreamServer {
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ servers: Vec<String>,
+ #[serde(default = "crate::Bool::<true>::value", skip_serializing_if = "crate::if_true")]
+ logQueries: bool,
+ #[serde(default = "crate::Bool::<true>::value", skip_serializing_if = "crate::if_true")]
+ logResponses: bool,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ bufferHint: u64,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ flushTimeout: u64,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ inputQueueSize: u64,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ outputQueueSize: u64,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ queueNotifyThreshold: u64,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ reopenInterval: u64,
+}
+
+// A dnstap logging NOD server
+#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
+#[serde(deny_unknown_fields)]
+pub struct DNSTapNODFrameStreamServer {
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ servers: Vec<String>,
+ #[serde(default = "crate::Bool::<true>::value", skip_serializing_if = "crate::if_true")]
+ logNODs: bool,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ logUDRs: bool,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ bufferHint: u64,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ flushTimeout: u64,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ inputQueueSize: u64,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ outputQueueSize: u64,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ queueNotifyThreshold: u64,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ reopenInterval: u64,
+}
+
+#[derive(Default, Deserialize, Serialize, Clone, Debug, PartialEq)]
+#[serde(deny_unknown_fields)]
+pub struct TSIGTriplet {
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ name: String,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ algo: String,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ secret: String,
+}
+
+#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
+#[serde(deny_unknown_fields)]
+pub struct RPZ {
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ addresses: Vec<String>,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ name: String,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ defcontent: String,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ defpol: String,
+ #[serde(default = "crate::Bool::<true>::value", skip_serializing_if = "crate::if_true")]
+ defpolOverrideLocalData: bool,
+ #[serde(default = "crate::U32::<{u32::MAX}>::value", skip_serializing_if = "crate::U32::<{u32::MAX}>::is_equal")]
+ defttl: u32,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ extendedErrorCode: u32,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ extendedErrorExtra: String,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ includeSOA: bool,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ ignoreDuplicates: bool,
+ #[serde(default = "crate::U32::<{u32::MAX}>::value", skip_serializing_if = "crate::U32::<{u32::MAX}>::is_equal")]
+ maxTTL: u32,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ policyName: String,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ tags: Vec<String>,
+ #[serde(default = "crate::Bool::<true>::value", skip_serializing_if = "crate::if_true")]
+ overridesGettag: bool,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ zoneSizeHint: u32,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ tsig: TSIGTriplet,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ refresh: u32,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ maxReceivedMBytes: u32,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ localAddress: String,
+ #[serde(default = "crate::U32::<20>::value", skip_serializing_if = "crate::U32::<20>::is_equal")]
+ axfrTimeout: u32,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ dumpFile: String,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ seedFile: String,
+}
+
+#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
+#[serde(deny_unknown_fields)]
+pub struct ZoneToCache {
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ zone: String,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ method: String,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ sources: Vec<String>,
+ #[serde(default = "crate::U64::<20>::value", skip_serializing_if = "crate::U64::<20>::is_equal")]
+ timeout: u64,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ tsig: TSIGTriplet,
+ #[serde(default = "crate::U64::<86400>::value", skip_serializing_if = "crate::U64::<86400>::is_equal")]
+ refreshPeriod: u64,
+ #[serde(default = "crate::U64::<60>::value", skip_serializing_if = "crate::U64::<60>::is_equal")]
+ retryOnErrorPeriod: u64,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ maxReceivedMBytes: u64,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ localAddress: String,
+ #[serde(default = "crate::def_ztc_validate", skip_serializing_if = "crate::def_value_equals_ztc_validate")]
+ zonemd: String,
+ #[serde(default = "crate::def_ztc_validate", skip_serializing_if = "crate::def_value_equals_ztc_validate")]
+ dnssec: String,
+}
+
+#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
+#[serde(deny_unknown_fields)]
+pub struct SubnetOrder {
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ subnet: String,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ order: u32,
+}
+
+#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
+#[serde(deny_unknown_fields)]
+pub struct SortList {
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ key: String,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ subnets: Vec<SubnetOrder>,
+}
+
+#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
+#[serde(deny_unknown_fields)]
+pub struct AllowedAdditionalQType {
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ qtype: String,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ targets: Vec<String>,
+ #[serde(default = "crate::def_additional_mode", skip_serializing_if = "crate::default_value_equals_additional_mode")]
+ mode: String,
+}
+
+#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
+#[serde(deny_unknown_fields)]
+pub struct ProxyMapping {
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ subnet: String,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ address: String,
+ #[serde(default, skip_serializing_if = "crate::is_default")]
+ domains: Vec<String>,
+}
+
+// A struct holding both a vector of forward zones and a vector o auth zones, used by REST API code
#[derive(Deserialize, Serialize, Debug, PartialEq)]
#[serde(deny_unknown_fields)]
-struct ApiZones {
+pub struct ApiZones {
#[serde(default, skip_serializing_if = "crate::is_default")]
auth_zones: Vec<AuthZone>,
#[serde(default, skip_serializing_if = "crate::is_default")]
vec_authzone_val: Vec<AuthZone>,
vec_trustanchor_val: Vec<TrustAnchor>,
vec_negativetrustanchor_val: Vec<NegativeTrustAnchor>,
+ vec_protobufserver_val: Vec<ProtobufServer>,
+ vec_dnstap_framestream_server_val: Vec<DNSTapFrameStreamServer>,
+ vec_dnstap_nod_framestream_server_val: Vec<DNSTapNODFrameStreamServer>,
+ vec_rpz_val: Vec<RPZ>,
+ vec_sortlist_val: Vec<SortList>,
+ vec_zonetocache_val: Vec<ZoneToCache>,
+ vec_allowedadditionalqtype_val: Vec<AllowedAdditionalQType>,
+ vec_proxymapping_val: Vec<ProxyMapping>,
}
struct OldStyle {
// Validate the sections inside the main settings struct, sections themselves will valdiate their fields
fn validate(self: &Recursorsettings) -> Result<()>;
- // The validate function bewlo are "hand-crafted" as their structs afre mnot generated
+ // The validate function below are "hand-crafted" as their structs are not generated
fn validate(self: &AuthZone, field: &str) -> Result<()>;
fn validate(self: &ForwardZone, field: &str) -> Result<()>;
fn validate(self: &TrustAnchor, field: &str) -> Result<()>;
}
}
-
impl Default for ApiZones {
fn default() -> Self {
let deserialized: ApiZones = serde_yaml::from_str("").unwrap();
serde_yaml::to_string(vec)
}
+fn insertb(map: &mut serde_yaml::Mapping, name: &str, val: bool) {
+ map.insert(
+ serde_yaml::Value::String(name.to_owned()),
+ serde_yaml::Value::Bool(val),
+ );
+}
+
+fn insertu(map: &mut serde_yaml::Mapping, name: &str, val: u64) {
+ map.insert(
+ serde_yaml::Value::String(name.to_owned()),
+ serde_yaml::Value::Number(serde_yaml::Number::from(val)),
+ );
+}
+
+fn insertu32(map: &mut serde_yaml::Mapping, name: &str, val: u32) {
+ map.insert(
+ serde_yaml::Value::String(name.to_owned()),
+ serde_yaml::Value::Number(serde_yaml::Number::from(val)),
+ );
+}
+
+fn inserts(map: &mut serde_yaml::Mapping, name: &str, val: &str) {
+ map.insert(
+ serde_yaml::Value::String(name.to_owned()),
+ serde_yaml::Value::String(val.to_owned()),
+ );
+}
+
+fn insertseq(map: &mut serde_yaml::Mapping, name: &str, val: &serde_yaml::Sequence) {
+ map.insert(
+ serde_yaml::Value::String(name.to_owned()),
+ serde_yaml::Value::Sequence(val.to_owned()),
+ );
+}
+
impl ForwardZone {
pub fn validate(&self, field: &str) -> Result<(), ValidationError> {
validate_name(&(field.to_owned() + ".zone"), &self.zone)?;
}
let mut map = serde_yaml::Mapping::new();
- map.insert(
- serde_yaml::Value::String("zone".to_owned()),
- serde_yaml::Value::String(self.zone.to_owned()),
- );
- map.insert(
- serde_yaml::Value::String("recurse".to_owned()),
- serde_yaml::Value::Bool(self.recurse),
- );
+ inserts(&mut map, "zone", &self.zone);
+ insertb(&mut map, "recurse", self.recurse);
map.insert(
serde_yaml::Value::String("forwarders".to_owned()),
serde_yaml::Value::Sequence(seq),
fn to_yaml_map(&self) -> serde_yaml::Value {
let mut map = serde_yaml::Mapping::new();
- map.insert(
- serde_yaml::Value::String("zone".to_owned()),
- serde_yaml::Value::String(self.zone.to_owned()),
- );
- map.insert(
- serde_yaml::Value::String("file".to_owned()),
- serde_yaml::Value::String(self.file.to_owned()),
- );
+ inserts(&mut map, "zone", &self.zone);
+ inserts(&mut map, "file", &self.file);
serde_yaml::Value::Mapping(map)
}
}
seq.push(serde_yaml::Value::String(entry.to_owned()));
}
let mut map = serde_yaml::Mapping::new();
- map.insert(
- serde_yaml::Value::String("name".to_owned()),
- serde_yaml::Value::String(self.name.to_owned()),
- );
- map.insert(
- serde_yaml::Value::String("dsrecord".to_owned()),
- serde_yaml::Value::Sequence(seq),
- );
+ inserts(&mut map, "name", &self.name);
+ insertseq(&mut map, "dsrecords", &seq);
serde_yaml::Value::Mapping(map)
}
}
fn to_yaml_map(&self) -> serde_yaml::Value {
let mut map = serde_yaml::Mapping::new();
+ inserts(&mut map, "name", &self.name);
+ inserts(&mut map, "reason", &self.reason);
+ serde_yaml::Value::Mapping(map)
+ }
+}
+
+impl ProtobufServer {
+ pub fn validate(&self, _field: &str) -> Result<(), ValidationError> {
+ Ok(())
+ }
+
+ fn to_yaml_map(&self) -> serde_yaml::Value {
+ let mut seq = serde_yaml::Sequence::new();
+ for entry in &self.servers {
+ seq.push(serde_yaml::Value::String(entry.to_owned()));
+ }
+ let mut map = serde_yaml::Mapping::new();
+ insertseq(&mut map, "servers", &seq);
+ insertu(&mut map, "timeout", self.timeout);
+ insertu(&mut map, "maxQueuedEntries", self.maxQueuedEntries);
+ insertu(&mut map, "reconnectWaitTime", self.reconnectWaitTime);
+ insertb(&mut map, "taggedOnly", self.taggedOnly);
+ insertb(&mut map, "asyncConnect", self.asyncConnect);
+ insertb(&mut map, "logQueries", self.logQueries);
+ insertb(&mut map, "logResponses", self.logResponses);
+ let mut seq2 = serde_yaml::Sequence::new();
+ for entry in &self.exportTypes {
+ seq2.push(serde_yaml::Value::String(entry.to_owned()));
+ }
+ insertseq(&mut map, "exportTypes", &seq2);
+ serde_yaml::Value::Mapping(map)
+ }
+}
+
+impl DNSTapFrameStreamServer {
+ pub fn validate(&self, _field: &str) -> Result<(), ValidationError> {
+ Ok(())
+ }
+
+ fn to_yaml_map(&self) -> serde_yaml::Value {
+ let mut seq = serde_yaml::Sequence::new();
+ for entry in &self.servers {
+ seq.push(serde_yaml::Value::String(entry.to_owned()));
+ }
+ let mut map = serde_yaml::Mapping::new();
+ insertseq(&mut map, "servers", &seq);
+ insertb(&mut map, "logQueries", self.logQueries);
+ insertb(&mut map, "logResponses", self.logResponses);
+ insertu(&mut map, "bufferHint", self.bufferHint);
+ insertu(&mut map, "flushTimeout", self.flushTimeout);
+ insertu(&mut map, "inputQueueSize", self.inputQueueSize);
+ insertu(&mut map, "outputQueueSize", self.outputQueueSize);
+ insertu(&mut map, "queueNotifyThreshold", self.queueNotifyThreshold);
+ insertu(&mut map, "reopenInterval", self.reopenInterval);
+ serde_yaml::Value::Mapping(map)
+ }
+}
+
+impl DNSTapNODFrameStreamServer {
+ pub fn validate(&self, _field: &str) -> Result<(), ValidationError> {
+ Ok(())
+ }
+
+ fn to_yaml_map(&self) -> serde_yaml::Value {
+ let mut seq = serde_yaml::Sequence::new();
+ for entry in &self.servers {
+ seq.push(serde_yaml::Value::String(entry.to_owned()));
+ }
+ let mut map = serde_yaml::Mapping::new();
+ insertseq(&mut map, "servers", &seq);
+ insertb(&mut map, "logNODs", self.logNODs);
+ insertb(&mut map, "logUDRs", self.logUDRs);
+ insertu(&mut map, "bufferHint", self.bufferHint);
+ insertu(&mut map, "flushTimeout", self.flushTimeout);
+ insertu(&mut map, "inputQueueSize", self.inputQueueSize);
+ insertu(&mut map, "outputQueueSize", self.outputQueueSize);
+ insertu(&mut map, "queueNotifyThreshold", self.queueNotifyThreshold);
+ insertu(&mut map, "reopenInterval", self.reopenInterval);
+ serde_yaml::Value::Mapping(map)
+ }
+}
+
+impl SortList {
+ pub fn validate(&self, _field: &str) -> Result<(), ValidationError> {
+ Ok(())
+ }
+
+ fn to_yaml_map(&self) -> serde_yaml::Value {
+ let mut map = serde_yaml::Mapping::new();
+ inserts(&mut map, "key", &self.key);
+ let mut seq = serde_yaml::Sequence::new();
+ for entry in &self.subnets {
+ let mut submap = serde_yaml::Mapping::new();
+ inserts(&mut submap, "subnet", &entry.subnet);
+ insertu32(&mut submap, "order", entry.order);
+ seq.push(serde_yaml::Value::Mapping(submap));
+ }
+ insertseq(&mut map, "subnets", &seq);
+ serde_yaml::Value::Mapping(map)
+ }
+}
+
+impl RPZ {
+ pub fn validate(&self, _field: &str) -> Result<(), ValidationError> {
+ Ok(())
+ }
+
+ fn to_yaml_map(&self) -> serde_yaml::Value {
+ let mut map = serde_yaml::Mapping::new();
+ let mut seq1 = serde_yaml::Sequence::new();
+ for entry in &self.addresses {
+ seq1.push(serde_yaml::Value::String(entry.to_owned()));
+ }
+ insertseq(&mut map, "addresses", &seq1);
+ inserts(&mut map, "name", &self.name);
+ inserts(&mut map, "defcontent", &self.defcontent);
+ inserts(&mut map, "defpol", &self.defpol);
+ insertb(
+ &mut map,
+ "defpolOverrideLocalData",
+ self.defpolOverrideLocalData,
+ );
+ insertu32(&mut map, "defttl", self.defttl);
+ insertu32(&mut map, "extendedErrorCode", self.extendedErrorCode);
+ insertb(&mut map, "includeSOA", self.includeSOA);
+ insertb(&mut map, "ignoreDuplicates", self.ignoreDuplicates);
+ insertu32(&mut map, "maxTTL", self.maxTTL);
+ inserts(&mut map, "policyName", &self.policyName);
+ let mut seq2 = serde_yaml::Sequence::new();
+ for entry in &self.tags {
+ seq2.push(serde_yaml::Value::String(entry.to_owned()));
+ }
+ insertseq(&mut map, "tags", &seq2);
+ insertb(&mut map, "overridesGettag", self.overridesGettag);
+ insertu32(&mut map, "zoneSizeHint", self.zoneSizeHint);
+
+ let mut tsigmap = serde_yaml::Mapping::new();
+ inserts(&mut tsigmap, "name", &self.tsig.name);
+ inserts(&mut tsigmap, "algo", &self.tsig.algo);
+ inserts(&mut tsigmap, "secret", &self.tsig.secret);
map.insert(
- serde_yaml::Value::String("name".to_owned()),
- serde_yaml::Value::String(self.name.to_owned()),
+ serde_yaml::Value::String("tsig".to_owned()),
+ serde_yaml::Value::Mapping(tsigmap),
);
+
+ insertu32(&mut map, "refresh", self.refresh);
+ insertu32(&mut map, "maxReceivedMBytes", self.maxReceivedMBytes);
+ inserts(&mut map, "localAddress", &self.localAddress);
+ insertu32(&mut map, "axfrTimeout", self.axfrTimeout);
+ inserts(&mut map, "dumpFile", &self.dumpFile);
+ inserts(&mut map, "seedFile", &self.seedFile);
+ serde_yaml::Value::Mapping(map)
+ }
+}
+
+impl ZoneToCache {
+ pub fn validate(&self, _field: &str) -> Result<(), ValidationError> {
+ Ok(())
+ }
+
+ fn to_yaml_map(&self) -> serde_yaml::Value {
+ let mut map = serde_yaml::Mapping::new();
+ inserts(&mut map, "zone", &self.zone);
+ inserts(&mut map, "method", &self.method);
+ let mut seq = serde_yaml::Sequence::new();
+ for entry in &self.sources {
+ seq.push(serde_yaml::Value::String(entry.to_owned()));
+ }
+ insertseq(&mut map, "sources", &seq);
+ insertu(&mut map, "timeout", self.timeout);
+
+ let mut tsigmap = serde_yaml::Mapping::new();
+ inserts(&mut tsigmap, "name", &self.tsig.name);
+ inserts(&mut tsigmap, "algo", &self.tsig.algo);
+ inserts(&mut tsigmap, "secret", &self.tsig.secret);
map.insert(
- serde_yaml::Value::String("reason".to_owned()),
- serde_yaml::Value::String(self.reason.to_owned()),
+ serde_yaml::Value::String("tsig".to_owned()),
+ serde_yaml::Value::Mapping(tsigmap),
);
+
+ insertu(&mut map, "refreshPeriod", self.refreshPeriod);
+ insertu(&mut map, "retryOnErrorPeriod", self.retryOnErrorPeriod);
+ insertu(&mut map, "maxReceivedMBytes", self.maxReceivedMBytes);
+ inserts(&mut map, "localAddress", &self.localAddress);
+ inserts(&mut map, "zonemd", &self.zonemd);
+ inserts(&mut map, "dnssec", &self.dnssec);
+
+ serde_yaml::Value::Mapping(map)
+ }
+}
+
+impl AllowedAdditionalQType {
+ pub fn validate(&self, _field: &str) -> Result<(), ValidationError> {
+ Ok(())
+ }
+
+ fn to_yaml_map(&self) -> serde_yaml::Value {
+ let mut map = serde_yaml::Mapping::new();
+ inserts(&mut map, "qtype", &self.qtype);
+ let mut seq = serde_yaml::Sequence::new();
+ for entry in &self.targets {
+ seq.push(serde_yaml::Value::String(entry.to_owned()));
+ }
+ insertseq(&mut map, "targets", &seq);
+ inserts(&mut map, "mode", &self.mode);
+ serde_yaml::Value::Mapping(map)
+ }
+}
+
+impl ProxyMapping {
+ pub fn validate(&self, _field: &str) -> Result<(), ValidationError> {
+ Ok(())
+ }
+
+ fn to_yaml_map(&self) -> serde_yaml::Value {
+ let mut map = serde_yaml::Mapping::new();
+ inserts(&mut map, "subnet", &self.subnet);
+ inserts(&mut map, "address", &self.address);
+ let mut seq = serde_yaml::Sequence::new();
+ for entry in &self.domains {
+ seq.push(serde_yaml::Value::String(entry.to_owned()));
+ }
+ insertseq(&mut map, "domains", &seq);
serde_yaml::Value::Mapping(map)
}
}
}
#[allow(clippy::ptr_arg)] //# Avoids creating a rust::Slice object on the C++ side.
-pub fn validate_trustanchors(
- field: &str,
- vec: &Vec<TrustAnchor>,
-) -> Result<(), ValidationError> {
+pub fn validate_trustanchors(field: &str, vec: &Vec<TrustAnchor>) -> Result<(), ValidationError> {
validate_vec(field, vec, |field, element| element.validate(field))
}
}
serde_yaml::Value::Sequence(seq)
}
- other => serde_yaml::Value::String("map_to_yaml_string: Unknown type: ".to_owned() + other),
+ "Vec<ProtobufServer>" => {
+ let mut seq = serde_yaml::Sequence::new();
+ for element in &entry.value.vec_protobufserver_val {
+ seq.push(element.to_yaml_map());
+ }
+ serde_yaml::Value::Sequence(seq)
+ }
+ "Vec<DNSTapFrameStreamServer>" => {
+ let mut seq = serde_yaml::Sequence::new();
+ for element in &entry.value.vec_dnstap_framestream_server_val {
+ seq.push(element.to_yaml_map());
+ }
+ serde_yaml::Value::Sequence(seq)
+ }
+ "Vec<DNSTapNODFrameStreamServer>" => {
+ let mut seq = serde_yaml::Sequence::new();
+ for element in &entry.value.vec_dnstap_nod_framestream_server_val {
+ seq.push(element.to_yaml_map());
+ }
+ serde_yaml::Value::Sequence(seq)
+ }
+ "Vec<RPZ>" => {
+ let mut seq = serde_yaml::Sequence::new();
+ for element in &entry.value.vec_rpz_val {
+ seq.push(element.to_yaml_map());
+ }
+ serde_yaml::Value::Sequence(seq)
+ }
+ "Vec<SortList>" => {
+ let mut seq = serde_yaml::Sequence::new();
+ for element in &entry.value.vec_sortlist_val {
+ seq.push(element.to_yaml_map());
+ }
+ serde_yaml::Value::Sequence(seq)
+ }
+ "Vec<ZoneToCache>" => {
+ let mut seq = serde_yaml::Sequence::new();
+ for element in &entry.value.vec_zonetocache_val {
+ seq.push(element.to_yaml_map());
+ }
+ serde_yaml::Value::Sequence(seq)
+ }
+ "Vec<AllowedAdditionalQType>" => {
+ let mut seq = serde_yaml::Sequence::new();
+ for element in &entry.value.vec_allowedadditionalqtype_val {
+ seq.push(element.to_yaml_map());
+ }
+ serde_yaml::Value::Sequence(seq)
+ }
+ "Vec<ProxyMapping>" => {
+ let mut seq = serde_yaml::Sequence::new();
+ for element in &entry.value.vec_proxymapping_val {
+ seq.push(element.to_yaml_map());
+ }
+ serde_yaml::Value::Sequence(seq)
+ }
+ other => serde_yaml::Value::String(
+ "map_to_yaml_string: Unknown type: ".to_owned() + other,
+ ),
};
if entry.overriding {
let tagged_value = Box::new(serde_yaml::value::TaggedValue {
zones.forward_zones.retain(|x| x.zone != zone);
api_write_zones(path, &zones)
}
+
+pub fn def_pb_export_qtypes() -> Vec<String> {
+ vec![
+ String::from("A"),
+ String::from("CNAME"),
+ String::from("AAAA"),
+ ]
+}
+
+pub fn default_value_equal_pb_export_qtypes(value: &Vec<String>) -> bool {
+ &def_pb_export_qtypes() == value
+}
+
+pub fn def_ztc_validate() -> String {
+ String::from("validate")
+}
+
+pub fn def_value_equals_ztc_validate(value: &String) -> bool {
+ &def_ztc_validate() == value
+}
+
+pub fn def_additional_mode() -> String {
+ String::from("CacheOnlyRequireAuth")
+}
+
+pub fn default_value_equals_additional_mode(value: &String) -> bool {
+ &def_additional_mode() == value
+}
}
}
+pub struct U32<const U: u32>;
+impl<const U: u32> U32<U> {
+ pub const fn value() -> u32 {
+ U
+ }
+ pub fn is_equal(v: &u32) -> bool {
+ v == &U
+ }
+}
+
// A helper to define constant value as a Rust path */
pub struct Bool<const U: bool>;
impl<const U: bool> Bool<U> {
'default' : '24',
'help' : 'XXX',
'doc' : ''',
+XXX
+ ''',
+ 'skip-old' : True,
+ 'versionadded': '5.1.0',
+ },
+ {
+ 'name' : 'protobuf_servers',
+ 'section' : 'logging',
+ 'type' : LType.ListProtobufServers,
+ 'default' : '',
+ 'help' : 'XXX',
+ 'doc' : ''',
+XXX
+ ''',
+ 'skip-old' : True,
+ 'versionadded': '5.1.0',
+ },
+ {
+ 'name' : 'outgoing_protobuf_servers',
+ 'section' : 'logging',
+ 'type' : LType.ListProtobufServers,
+ 'default' : '',
+ 'help' : 'XXX',
+ 'doc' : ''',
+XXX
+ ''',
+ 'skip-old' : True,
+ 'versionadded': '5.1.0',
+ },
+ {
+ 'name' : 'dnstap_framestream_servers',
+ 'section' : 'logging',
+ 'type' : LType.ListDNSTapFrameStreamServers,
+ 'default' : '',
+ 'help' : 'XXX',
+ 'doc' : ''',
+XXX
+ ''',
+ 'skip-old' : True,
+ 'versionadded': '5.1.0',
+ },
+ {
+ 'name' : 'dnstap_nod_framestream_servers',
+ 'section' : 'logging',
+ 'type' : LType.ListDNSTapNODFrameStreamServers,
+ 'default' : '',
+ 'help' : 'XXX',
+ 'doc' : ''',
+XXX
+ ''',
+ 'skip-old' : True,
+ 'versionadded': '5.1.0',
+ },
+ {
+ 'name' : 'sortlists',
+ 'section' : 'recursor',
+ 'type' : LType.ListSortLists,
+ 'default' : '',
+ 'help' : 'XXX',
+ 'doc' : ''',
+XXX
+ ''',
+ 'skip-old' : True,
+ 'versionadded': '5.1.0',
+ },
+ {
+ 'name' : 'rpzs',
+ 'section' : 'recursor',
+ 'type' : LType.ListRPZs,
+ 'default' : '',
+ 'help' : 'XXX',
+ 'doc' : ''',
+XXX
+ ''',
+ 'skip-old' : True,
+ 'versionadded': '5.1.0',
+ },
+ {
+ 'name' : 'zonetocaches',
+ 'section' : 'recordcache',
+ 'type' : LType.ListZoneToCaches,
+ 'default' : '',
+ 'help' : 'XXX',
+ 'doc' : ''',
+XXX
+ ''',
+ 'skip-old' : True,
+ 'versionadded': '5.1.0',
+ },
+ {
+ 'name' : 'allowed_additional_qtypes',
+ 'section' : 'recursor',
+ 'type' : LType.ListAllowedAdditionalQTypes,
+ 'default' : '',
+ 'help' : 'XXX',
+ 'doc' : ''',
+XXX
+ ''',
+ 'skip-old' : True,
+ 'versionadded': '5.1.0',
+ },
+ {
+ 'name' : 'proxymappings',
+ 'section' : 'incoming',
+ 'type' : LType.ListProxyMappings,
+ 'default' : '',
+ 'help' : 'XXX',
+ 'doc' : ''',
XXX
''',
'skip-old' : True,
BOOST_CHECK_EQUAL(lhs.recordcache.max_entries, 99U);
}
+BOOST_AUTO_TEST_CASE(test_yaml_defaults_ta)
+{
+ // Two entries: one all default, one all overrides
+ const std::string yaml = R"EOT(dnssec:
+ trustanchors:
+ - name: a
+ dsrecords: [b]
+ negative_trustanchors:
+ - name: c
+ reason: d
+ trustanchorfile: e
+ trustanchorfile_interval: 99
+)EOT";
+ auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml);
+ settings.validate();
+ BOOST_CHECK_EQUAL(std::string(settings.dnssec.trustanchors[0].name), "a");
+ BOOST_CHECK_EQUAL(std::string(settings.dnssec.trustanchors[0].dsrecords[0]), "b");
+ BOOST_CHECK_EQUAL(std::string(settings.dnssec.negative_trustanchors[0].name), "c");
+ BOOST_CHECK_EQUAL(std::string(settings.dnssec.negative_trustanchors[0].reason), "d");
+ BOOST_CHECK_EQUAL(std::string(settings.dnssec.trustanchorfile), "e");
+ BOOST_CHECK_EQUAL(settings.dnssec.trustanchorfile_interval, 99U);
+}
+
+BOOST_AUTO_TEST_CASE(test_yaml_defaults_protobuf)
+{
+ // Two entries: one all default, one all overrides
+ const std::string yaml = R"EOT(logging:
+ protobuf_servers:
+ - servers: [a]
+ - servers: [b]
+ timeout: 100
+ maxQueuedEntries: 101
+ reconnectWaitTime: 102
+ taggedOnly: true
+ asyncConnect: true
+ logQueries: false
+ logResponses: false
+ logMappedFrom: true
+)EOT";
+
+ auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml);
+ settings.validate();
+ BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[0].timeout, 2U);
+ BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[0].maxQueuedEntries, 100U);
+ BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[0].reconnectWaitTime, 1U);
+ BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[0].taggedOnly, false);
+ BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[0].asyncConnect, false);
+ BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[0].logQueries, true);
+ BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[0].logResponses, true);
+ // Code below crashes clang
+ // std::vector<string> testv = {"A", "AAAA", "CNAME"})
+ // BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[0].exportTypes, testv);
+ BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[0].logMappedFrom, false);
+
+ BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[1].timeout, 100U);
+ BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[1].maxQueuedEntries, 101U);
+ BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[1].reconnectWaitTime, 102U);
+ BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[1].taggedOnly, true);
+ BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[1].asyncConnect, true);
+ BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[1].logQueries, false);
+ BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[1].logResponses, false);
+ BOOST_CHECK_EQUAL(settings.logging.protobuf_servers[1].logMappedFrom, true);
+}
+
+BOOST_AUTO_TEST_CASE(test_yaml_defaults_outgoing_protobuf)
+{
+ // Two entries: one all default, one all overrides
+ const std::string yaml = R"EOT(logging:
+ outgoing_protobuf_servers:
+ - servers: [a]
+ - servers: [b]
+ timeout: 100
+ maxQueuedEntries: 101
+ reconnectWaitTime: 102
+ taggedOnly: true
+ asyncConnect: true
+ logQueries: false
+ logResponses: false
+ logMappedFrom: true
+)EOT";
+
+ auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml);
+ settings.validate();
+ BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[0].timeout, 2U);
+ BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[0].maxQueuedEntries, 100U);
+ BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[0].reconnectWaitTime, 1U);
+ BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[0].taggedOnly, false);
+ BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[0].asyncConnect, false);
+ BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[0].logQueries, true);
+ BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[0].logResponses, true);
+ // Code below crashes clang
+ // std::vector<string> testv = {"A", "AAAA", "CNAME"})
+ // BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[0].exportTypes, testv);
+ BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[0].logMappedFrom, false);
+
+ BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[1].timeout, 100U);
+ BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[1].maxQueuedEntries, 101U);
+ BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[1].reconnectWaitTime, 102U);
+ BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[1].taggedOnly, true);
+ BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[1].asyncConnect, true);
+ BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[1].logQueries, false);
+ BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[1].logResponses, false);
+ BOOST_CHECK_EQUAL(settings.logging.outgoing_protobuf_servers[1].logMappedFrom, true);
+}
+
+BOOST_AUTO_TEST_CASE(test_yaml_defaults_dnstap)
+{
+ // Two entries: one all default, one all overrides
+ const std::string yaml = R"EOT(logging:
+ dnstap_framestream_servers:
+ - servers: [a]
+ - servers: [b]
+ logQueries: false
+ logResponses: false
+ bufferHint: 1
+ flushTimeout: 2
+ inputQueueSize: 3
+ outputQueueSize: 4
+ queueNotifyThreshold: 5
+ reopenInterval: 6
+)EOT";
+
+ auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml);
+ settings.validate();
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_framestream_servers[0].logQueries, true);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_framestream_servers[0].logResponses, true);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_framestream_servers[0].bufferHint, 0U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_framestream_servers[0].flushTimeout, 0U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_framestream_servers[0].inputQueueSize, 0U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_framestream_servers[0].outputQueueSize, 0U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_framestream_servers[0].queueNotifyThreshold, 0U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_framestream_servers[0].reopenInterval, 0U);
+
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_framestream_servers[1].logQueries, false);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_framestream_servers[1].logResponses, false);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_framestream_servers[1].bufferHint, 1U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_framestream_servers[1].flushTimeout, 2U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_framestream_servers[1].inputQueueSize, 3U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_framestream_servers[1].outputQueueSize, 4U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_framestream_servers[1].queueNotifyThreshold, 5U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_framestream_servers[1].reopenInterval, 6U);
+}
+
+BOOST_AUTO_TEST_CASE(test_yaml_defaults_dnstapnod)
+{
+ // Two entries: one all default, one all overrides
+ const std::string yaml = R"EOT(logging:
+ dnstap_nod_framestream_servers:
+ - servers: [a]
+ - servers: [b]
+ logNODs: false
+ logUDRs: true
+ bufferHint: 1
+ flushTimeout: 2
+ inputQueueSize: 3
+ outputQueueSize: 4
+ queueNotifyThreshold: 5
+ reopenInterval: 6
+)EOT";
+
+ auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml);
+ settings.validate();
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_nod_framestream_servers[0].logNODs, true);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_nod_framestream_servers[0].logUDRs, false);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_nod_framestream_servers[0].bufferHint, 0U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_nod_framestream_servers[0].flushTimeout, 0U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_nod_framestream_servers[0].inputQueueSize, 0U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_nod_framestream_servers[0].outputQueueSize, 0U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_nod_framestream_servers[0].queueNotifyThreshold, 0U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_nod_framestream_servers[0].reopenInterval, 0U);
+
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_nod_framestream_servers[1].logNODs, false);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_nod_framestream_servers[1].logUDRs, true);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_nod_framestream_servers[1].bufferHint, 1U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_nod_framestream_servers[1].flushTimeout, 2U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_nod_framestream_servers[1].inputQueueSize, 3U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_nod_framestream_servers[1].outputQueueSize, 4U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_nod_framestream_servers[1].queueNotifyThreshold, 5U);
+ BOOST_CHECK_EQUAL(settings.logging.dnstap_nod_framestream_servers[1].reopenInterval, 6U);
+}
+
+BOOST_AUTO_TEST_CASE(test_yaml_defaults_rpz)
+{
+ // Two entries: one all default, one all overrides
+ const std::string yaml = R"EOT(recursor:
+ rpzs:
+ - name: file
+ - name: zone
+ addresses: [1.2.3.4]
+ - name: nondef
+ addresses: [1.2.3.4]
+ defcontent: a
+ defpol: b
+ defpolOverrideLocalData: false
+ defttl: 99
+ extendedErrorCode: 100
+ extendedErrorExtra: c
+ includeSOA: true
+ ignoreDuplicates: true
+ maxTTL: 101
+ policyName: c
+ tags: [d,e]
+ overridesGettag: false
+ zoneSizeHint: 102
+ tsig:
+ name: f
+ algo: g
+ secret: h
+ refresh: 103
+ maxReceivedMBytes: 104
+ localAddress: i
+ axfrTimeout: 105
+ dumpFile: j
+ seedFile: k
+)EOT";
+
+ auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml);
+ settings.validate();
+
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[0].name), "file");
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[0].defcontent), "");
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[0].defpol), "");
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[0].defpolOverrideLocalData, true);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[0].defttl, -1U);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[0].extendedErrorCode, 0U);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[0].extendedErrorExtra, "");
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[0].includeSOA, false);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[0].ignoreDuplicates, false);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[0].maxTTL, -1U);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[0].tags.size(), 0U);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[0].overridesGettag, true);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[0].zoneSizeHint, 0U);
+
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[1].name), "zone");
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[1].addresses[0]), "1.2.3.4");
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[1].tsig.name), "");
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[1].tsig.algo), "");
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[1].tsig.secret), "");
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[1].refresh, 0U);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[1].maxReceivedMBytes, 0U);
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[1].localAddress), "");
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[1].axfrTimeout, 20U);
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[1].dumpFile), "");
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[1].seedFile), "");
+
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[2].name), "nondef");
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[1].addresses[0]), "1.2.3.4");
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[2].defcontent), "a");
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[2].defpol), "b");
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[2].defpolOverrideLocalData, false);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[2].defttl, 99U);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[2].extendedErrorCode, 100U);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[2].extendedErrorExtra, "c");
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[2].includeSOA, true);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[2].ignoreDuplicates, true);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[2].maxTTL, 101U);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[2].tags.size(), 2U);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[2].overridesGettag, false);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[2].zoneSizeHint, 102U);
+
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[2].tsig.name), "f");
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[2].tsig.algo), "g");
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[2].tsig.secret), "h");
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[2].refresh, 103U);
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[2].maxReceivedMBytes, 104U);
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[2].localAddress), "i");
+ BOOST_CHECK_EQUAL(settings.recursor.rpzs[2].axfrTimeout, 105U);
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[2].dumpFile), "j");
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.rpzs[2].seedFile), "k");
+}
+
+BOOST_AUTO_TEST_CASE(test_yaml_sortlist)
+{
+ const std::string yaml = R"EOT(recursor:
+ sortlists:
+ - key: 1.2.3.4/8
+ subnets:
+ - subnet: 5.6.7.8
+ order: 99
+)EOT";
+
+ auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml);
+ settings.validate();
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.sortlists[0].key), "1.2.3.4/8");
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.sortlists[0].subnets[0].subnet), "5.6.7.8");
+ BOOST_CHECK_EQUAL(settings.recursor.sortlists[0].subnets[0].order, 99U);
+}
+
+BOOST_AUTO_TEST_CASE(test_yaml_ztc)
+{
+ const std::string yaml = R"EOT(recordcache:
+ zonetocaches:
+ - zone: zone
+ method: axfr
+ sources: [1.2.3.4]
+ - zone: zone2
+ method: axfr
+ sources: [1.2.3.4]
+ timeout: 1
+ tsig:
+ name: a
+ algo: b
+ secret: c
+ refreshPeriod: 2
+ retryOnErrorPeriod: 3
+ maxReceivedMBytes: 4
+ localAddress: d
+ zonemd: ignore
+ dnssec: require
+)EOT";
+
+ auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml);
+ settings.validate();
+ BOOST_CHECK_EQUAL(std::string(settings.recordcache.zonetocaches[0].zone), "zone");
+ BOOST_CHECK_EQUAL(std::string(settings.recordcache.zonetocaches[0].method), "axfr");
+ BOOST_CHECK_EQUAL(std::string(settings.recordcache.zonetocaches[0].sources[0]), "1.2.3.4");
+ BOOST_CHECK_EQUAL(settings.recordcache.zonetocaches[0].timeout, 20U);
+ BOOST_CHECK_EQUAL(std::string(settings.recordcache.zonetocaches[0].tsig.name), "");
+ BOOST_CHECK_EQUAL(std::string(settings.recordcache.zonetocaches[0].tsig.algo), "");
+ BOOST_CHECK_EQUAL(std::string(settings.recordcache.zonetocaches[0].tsig.secret), "");
+ BOOST_CHECK_EQUAL(settings.recordcache.zonetocaches[0].refreshPeriod, 86400U);
+ BOOST_CHECK_EQUAL(settings.recordcache.zonetocaches[0].retryOnErrorPeriod, 60U);
+ BOOST_CHECK_EQUAL(settings.recordcache.zonetocaches[0].maxReceivedMBytes, 0U);
+ BOOST_CHECK_EQUAL(settings.recordcache.zonetocaches[0].localAddress, "");
+ BOOST_CHECK_EQUAL(settings.recordcache.zonetocaches[0].zonemd, "validate");
+ BOOST_CHECK_EQUAL(settings.recordcache.zonetocaches[0].dnssec, "validate");
+
+ BOOST_CHECK_EQUAL(std::string(settings.recordcache.zonetocaches[1].zone), "zone2");
+ BOOST_CHECK_EQUAL(std::string(settings.recordcache.zonetocaches[1].method), "axfr");
+ BOOST_CHECK_EQUAL(std::string(settings.recordcache.zonetocaches[1].sources[0]), "1.2.3.4");
+ BOOST_CHECK_EQUAL(settings.recordcache.zonetocaches[1].timeout, 1U);
+ BOOST_CHECK_EQUAL(std::string(settings.recordcache.zonetocaches[1].tsig.name), "a");
+ BOOST_CHECK_EQUAL(std::string(settings.recordcache.zonetocaches[1].tsig.algo), "b");
+ BOOST_CHECK_EQUAL(std::string(settings.recordcache.zonetocaches[1].tsig.secret), "c");
+ BOOST_CHECK_EQUAL(settings.recordcache.zonetocaches[1].refreshPeriod, 2U);
+ BOOST_CHECK_EQUAL(settings.recordcache.zonetocaches[1].retryOnErrorPeriod, 3U);
+ BOOST_CHECK_EQUAL(settings.recordcache.zonetocaches[1].maxReceivedMBytes, 4U);
+ BOOST_CHECK_EQUAL(settings.recordcache.zonetocaches[1].localAddress, "d");
+ BOOST_CHECK_EQUAL(settings.recordcache.zonetocaches[1].zonemd, "ignore");
+ BOOST_CHECK_EQUAL(settings.recordcache.zonetocaches[1].dnssec, "require");
+}
+
+BOOST_AUTO_TEST_CASE(test_yaml_additionals)
+{
+ const std::string yaml = R"EOT(recursor:
+ allowed_additional_qtypes:
+ - qtype: A
+ targets: [A, MX, AAAA]
+ - qtype: MX
+ targets: [A]
+ mode: CacheOnly
+)EOT";
+
+ auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml);
+ settings.validate();
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.allowed_additional_qtypes[0].qtype), "A");
+ BOOST_CHECK_EQUAL(settings.recursor.allowed_additional_qtypes[0].targets.size(), 3U);
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.allowed_additional_qtypes[0].mode), "CacheOnlyRequireAuth");
+
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.allowed_additional_qtypes[1].qtype), "MX");
+ BOOST_CHECK_EQUAL(settings.recursor.allowed_additional_qtypes[1].targets.size(), 1U);
+ BOOST_CHECK_EQUAL(std::string(settings.recursor.allowed_additional_qtypes[1].mode), "CacheOnly");
+}
+
+BOOST_AUTO_TEST_CASE(test_yaml_proxymapping)
+{
+ const std::string yaml = R"EOT(incoming:
+ proxymappings:
+ - subnet: 1.2.3.4
+ address: 4.5.6.7
+ - subnet: 3.4.5.6
+ address: 6.7.8.9
+ domains: [a, b, c]
+)EOT";
+
+ auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml);
+ settings.validate();
+ BOOST_CHECK_EQUAL(std::string(settings.incoming.proxymappings[0].subnet), "1.2.3.4");
+ BOOST_CHECK_EQUAL(std::string(settings.incoming.proxymappings[0].address), "4.5.6.7");
+ BOOST_CHECK_EQUAL(settings.incoming.proxymappings[0].domains.size(), 0U);
+
+ BOOST_CHECK_EQUAL(std::string(settings.incoming.proxymappings[1].subnet), "3.4.5.6");
+ BOOST_CHECK_EQUAL(std::string(settings.incoming.proxymappings[1].address), "6.7.8.9");
+ BOOST_CHECK_EQUAL(settings.incoming.proxymappings[1].domains.size(), 3U);
+}
+
BOOST_AUTO_TEST_SUITE_END()