mirror of
https://github.com/alexhopeoconnor/dnsmasq-webui.git
synced 2026-10-22 13:57:50 +10:00
Effective config: do-0x20-encode revert fix, validation UI, custom displays, option help
- Fix do-0x20-encode: clearing pending when toggling back to original (Disabled/Default) - Do0x20EncodeDisplay: uncheck uses pending.OldValue when present - EffectiveConfigFieldDisplay: use pending.OldValue as _valueAtActivation when re-entering with pending - Effective config: validation errors/warnings in toolbar and save modal, revert from modal - Custom displays: Do0x20EncodeDisplay (tri-state), KeyOnlyOrValueDisplay - ExplicitToggleState, config/apply support for do-0x20-encode, option help and tests
This commit is contained in:
@@ -148,4 +148,63 @@ public static class DnsmasqConfKeys
|
||||
// --- Niche / platform (Linux conntrack mark for UBus/query filtering) ---
|
||||
public const string Conntrack = "conntrack";
|
||||
|
||||
public const string ConnmarkAllowlistEnable = "connmark-allowlist-enable";
|
||||
public const string NoRoundRobin = "no-round-robin";
|
||||
public const string DnssecNoTimecheck = "dnssec-no-timecheck";
|
||||
public const string DnssecDebug = "dnssec-debug";
|
||||
public const string Leasequery = "leasequery";
|
||||
public const string DhcpGenerateNames = "dhcp-generate-names";
|
||||
public const string DhcpBroadcast = "dhcp-broadcast";
|
||||
public const string DhcpSequentialIp = "dhcp-sequential-ip";
|
||||
public const string DhcpIgnoreClid = "dhcp-ignore-clid";
|
||||
public const string BootpDynamic = "bootp-dynamic";
|
||||
public const string NoPing = "no-ping";
|
||||
public const string ScriptArp = "script-arp";
|
||||
public const string ScriptOnRenewal = "script-on-renewal";
|
||||
public const string DhcpNoOverride = "dhcp-no-override";
|
||||
public const string QuietDhcp = "quiet-dhcp";
|
||||
public const string QuietDhcp6 = "quiet-dhcp6";
|
||||
public const string QuietRa = "quiet-ra";
|
||||
public const string QuietTftp = "quiet-tftp";
|
||||
|
||||
public const string DnsForwardMax = "dns-forward-max";
|
||||
public const string Dumpfile = "dumpfile";
|
||||
public const string Dumpmask = "dumpmask";
|
||||
public const string AddCpeId = "add-cpe-id";
|
||||
public const string DnssecTimestamp = "dnssec-timestamp";
|
||||
public const string DnssecLimits = "dnssec-limits";
|
||||
public const string DhcpAlternatePort = "dhcp-alternate-port";
|
||||
public const string DhcpDuid = "dhcp-duid";
|
||||
public const string DhcpLuascript = "dhcp-luascript";
|
||||
public const string DhcpScriptuser = "dhcp-scriptuser";
|
||||
public const string DhcpPxeVendor = "dhcp-pxe-vendor";
|
||||
|
||||
public const string ConnmarkAllowlist = "connmark-allowlist";
|
||||
public const string CaaRecord = "caa-record";
|
||||
public const string DnsRr = "dns-rr";
|
||||
public const string SynthDomain = "synth-domain";
|
||||
public const string AuthZone = "auth-zone";
|
||||
public const string AuthSoa = "auth-soa";
|
||||
public const string AuthSecServers = "auth-sec-servers";
|
||||
public const string AuthPeer = "auth-peer";
|
||||
public const string DhcpRelay = "dhcp-relay";
|
||||
public const string DhcpCircuitid = "dhcp-circuitid";
|
||||
public const string DhcpRemoteid = "dhcp-remoteid";
|
||||
public const string DhcpSubscrid = "dhcp-subscrid";
|
||||
public const string DhcpProxy = "dhcp-proxy";
|
||||
public const string TagIf = "tag-if";
|
||||
public const string BridgeInterface = "bridge-interface";
|
||||
public const string SharedNetwork = "shared-network";
|
||||
public const string DhcpOptionPxe = "dhcp-option-pxe";
|
||||
|
||||
public const string UseStaleCache = "use-stale-cache";
|
||||
public const string AddMac = "add-mac";
|
||||
public const string StripMac = "strip-mac";
|
||||
public const string AddSubnet = "add-subnet";
|
||||
public const string StripSubnet = "strip-subnet";
|
||||
public const string Umbrella = "umbrella";
|
||||
|
||||
public const string Do0x20Encode = "do-0x20-encode";
|
||||
public const string No0x20Encode = "no-0x20-encode";
|
||||
|
||||
}
|
||||
|
||||
@@ -57,6 +57,11 @@ public static class DnsmasqOptionTooltips
|
||||
[DnsmasqConfKeys.NoDhcpv6Interface] = "No DHCPv6/RA on these interfaces. Can repeat.",
|
||||
[DnsmasqConfKeys.Ipset] = "Add resolved IPs to ipset (domain, set names). Can repeat.",
|
||||
[DnsmasqConfKeys.Nftset] = "Add resolved IPs to nftables sets. Can repeat.",
|
||||
[DnsmasqConfKeys.ConnmarkAllowlistEnable] = "Use conntrack marks to allowlist which queries are forwarded (with connmark-allowlist).",
|
||||
[DnsmasqConfKeys.NoRoundRobin] = "Do not rotate the order of upstream servers for each query.",
|
||||
[DnsmasqConfKeys.DnsForwardMax] = "Maximum number of concurrent DNS forwards (default 150).",
|
||||
[DnsmasqConfKeys.ConnmarkAllowlist] = "Conntrack marks that allowlist which queries are forwarded (with connmark-allowlist-enable). Can repeat.",
|
||||
[DnsmasqConfKeys.Do0x20Encode] = "Use 0x20 encoding in queries to detect DNS poisoning (Enabled), disable it (Disabled), or default (not set).",
|
||||
|
||||
// --- DNS records ---
|
||||
[DnsmasqConfKeys.Domain] = "Local domain(s); optional IP. Can repeat (e.g. domain=home,192.168.1.1).",
|
||||
@@ -72,12 +77,33 @@ public static class DnsmasqOptionTooltips
|
||||
[DnsmasqConfKeys.HostRecord] = "A/AAAA host records (name, IP). Can repeat.",
|
||||
[DnsmasqConfKeys.DynamicHost] = "Dynamic host entries. Can repeat.",
|
||||
[DnsmasqConfKeys.InterfaceName] = "Name per interface (for localise-queries). Can repeat.",
|
||||
[DnsmasqConfKeys.CaaRecord] = "CAA record (domain, flags, tag, value). Can repeat.",
|
||||
[DnsmasqConfKeys.DnsRr] = "Arbitrary DNS resource record. Can repeat.",
|
||||
[DnsmasqConfKeys.SynthDomain] = "Synthesize answers for a domain. Can repeat.",
|
||||
[DnsmasqConfKeys.AuthZone] = "Authoritative zone (domain, subnet). Can repeat.",
|
||||
[DnsmasqConfKeys.AuthSoa] = "SOA record for authoritative zone. Can repeat.",
|
||||
[DnsmasqConfKeys.AuthSecServers] = "Secondary servers for zone transfer. Can repeat.",
|
||||
[DnsmasqConfKeys.AuthPeer] = "Peers for zone transfer. Can repeat.",
|
||||
|
||||
// --- DHCP ---
|
||||
[DnsmasqConfKeys.DhcpAuthoritative] = "DHCP server is authoritative; required for DHCP to work.",
|
||||
[DnsmasqConfKeys.DhcpRapidCommit] = "DHCPv4 Rapid Commit (RFC 4039); use only if single server or all commit.",
|
||||
[DnsmasqConfKeys.Leasequery] = "Respond to DHCPLEASEQUERY messages (e.g. from relay).",
|
||||
[DnsmasqConfKeys.DhcpGenerateNames] = "Generate names for DHCP clients from their hostname or MAC.",
|
||||
[DnsmasqConfKeys.DhcpBroadcast] = "Use broadcast to communicate with DHCP clients when unicast is not possible.",
|
||||
[DnsmasqConfKeys.DhcpSequentialIp] = "Allocate DHCP addresses sequentially from the range.",
|
||||
[DnsmasqConfKeys.DhcpIgnoreClid] = "Ignore client identifier (use MAC only) for DHCP.",
|
||||
[DnsmasqConfKeys.BootpDynamic] = "Allow dynamic allocation for BOOTP clients.",
|
||||
[DnsmasqConfKeys.NoPing] = "Do not ping the gateway before offering a DHCP lease.",
|
||||
[DnsmasqConfKeys.ScriptArp] = "Call dhcp-script with extra 'arp' or 'arp-old arp-new' for ARP table updates.",
|
||||
[DnsmasqConfKeys.ScriptOnRenewal] = "Call dhcp-script on lease renewal (in addition to first assignment).",
|
||||
[DnsmasqConfKeys.DhcpNoOverride] = "Do not replace existing DNS/DHCP data for a client (e.g. from /etc/hosts).",
|
||||
[DnsmasqConfKeys.DhcpScript] = "Script run on lease add/delete (add|del, MAC, IP, hostname).",
|
||||
[DnsmasqConfKeys.LeasefileRo] = "Do not create or truncate the DHCP lease file.",
|
||||
[DnsmasqConfKeys.DhcpAlternatePort] = "Use alternate port for DHCP (e.g. 67).",
|
||||
[DnsmasqConfKeys.DhcpDuid] = "DHCP unique identifier (DUID) for the server.",
|
||||
[DnsmasqConfKeys.DhcpLuascript] = "Lua script for DHCP (e.g. for custom logic).",
|
||||
[DnsmasqConfKeys.DhcpScriptuser] = "User to run dhcp-script as (requires root).",
|
||||
[DnsmasqConfKeys.DhcpLeasefile] = "Path to the DHCP lease file.",
|
||||
[DnsmasqConfKeys.DhcpLeaseMax] = "Maximum number of DHCP leases to hold.",
|
||||
[DnsmasqConfKeys.DhcpTtl] = "TTL for DHCP names in the DNS cache.",
|
||||
@@ -98,6 +124,14 @@ public static class DnsmasqOptionTooltips
|
||||
[DnsmasqConfKeys.DhcpUserclass] = "Match by DHCP user class. Can repeat.",
|
||||
[DnsmasqConfKeys.RaParam] = "Router advertisement parameters (DHCPv6/RA). Can repeat.",
|
||||
[DnsmasqConfKeys.Slaac] = "SLAAC host part for DHCPv6/RA. Can repeat.",
|
||||
[DnsmasqConfKeys.DhcpRelay] = "Relay DHCP to another server. Can repeat.",
|
||||
[DnsmasqConfKeys.DhcpCircuitid] = "Circuit ID for DHCP relay. Can repeat.",
|
||||
[DnsmasqConfKeys.DhcpRemoteid] = "Remote ID for DHCP relay. Can repeat.",
|
||||
[DnsmasqConfKeys.DhcpSubscrid] = "Subscriber ID for DHCP relay. Can repeat.",
|
||||
[DnsmasqConfKeys.DhcpProxy] = "DHCP proxy (relay) configuration. Can repeat.",
|
||||
[DnsmasqConfKeys.TagIf] = "Set tag when request from interface. Can repeat.",
|
||||
[DnsmasqConfKeys.BridgeInterface] = "Bridge interfaces for DHCP. Can repeat.",
|
||||
[DnsmasqConfKeys.SharedNetwork] = "Shared network for DHCP. Can repeat.",
|
||||
|
||||
// --- TFTP / PXE ---
|
||||
[DnsmasqConfKeys.EnableTftp] = "Enable the built-in TFTP server.",
|
||||
@@ -107,10 +141,17 @@ public static class DnsmasqOptionTooltips
|
||||
[DnsmasqConfKeys.TftpRoot] = "Root directory for TFTP files.",
|
||||
[DnsmasqConfKeys.PxePrompt] = "PXE boot prompt (e.g. timeout,0 to disable).",
|
||||
[DnsmasqConfKeys.PxeService] = "PXE service definitions. Can repeat.",
|
||||
[DnsmasqConfKeys.DhcpPxeVendor] = "PXE vendor class string (e.g. for PXE matching).",
|
||||
[DnsmasqConfKeys.DhcpOptionPxe] = "PXE option (e.g. option 43). Can repeat.",
|
||||
|
||||
// --- DNSSEC ---
|
||||
[DnsmasqConfKeys.Dnssec] = "Validate DNSSEC on replies from upstream.",
|
||||
[DnsmasqConfKeys.DnssecCheckUnsigned] = "Treat unsigned zones as bogus.",
|
||||
[DnsmasqConfKeys.DnssecNoTimecheck] = "Do not validate DNSSEC signatures against the current time (e.g. for testing).",
|
||||
[DnsmasqConfKeys.DnssecDebug] = "Log DNSSEC validation failures at debug level.",
|
||||
[DnsmasqConfKeys.AddCpeId] = "Add CPE-ID to DHCP requests (for identification).",
|
||||
[DnsmasqConfKeys.DnssecTimestamp] = "Path to file for DNSSEC timestamp (e.g. for validation).",
|
||||
[DnsmasqConfKeys.DnssecLimits] = "DNSSEC validation limits (e.g. max signed zones).",
|
||||
[DnsmasqConfKeys.TrustAnchor] = "DNSSEC trust anchors. Can repeat.",
|
||||
|
||||
// --- Cache ---
|
||||
@@ -121,6 +162,12 @@ public static class DnsmasqOptionTooltips
|
||||
[DnsmasqConfKeys.MaxTtl] = "Maximum TTL for cached responses (cap on upstream TTL).",
|
||||
[DnsmasqConfKeys.MaxCacheTtl] = "Maximum TTL for positive cache entries.",
|
||||
[DnsmasqConfKeys.MinCacheTtl] = "Minimum TTL for positive cache entries.",
|
||||
[DnsmasqConfKeys.Dumpfile] = "Dump cache to this file (for debugging).",
|
||||
[DnsmasqConfKeys.Dumpmask] = "Mask for cache dump (which data to include).",
|
||||
[DnsmasqConfKeys.UseStaleCache] = "Use stale cache when upstream is unavailable. Off, On (key-only), or custom seconds.",
|
||||
[DnsmasqConfKeys.AddMac] = "Add MAC address to DNS queries. Off, On (key-only), or custom value.",
|
||||
[DnsmasqConfKeys.AddSubnet] = "Add subnet to DNS queries. Off, On (key-only), or custom value.",
|
||||
[DnsmasqConfKeys.Umbrella] = "Cisco Umbrella device identity. Off, On (key-only), or custom value.",
|
||||
|
||||
// --- Process & networking ---
|
||||
[DnsmasqConfKeys.NoPoll] = "Do not poll /etc/resolv.conf for changes.",
|
||||
@@ -143,6 +190,10 @@ public static class DnsmasqOptionTooltips
|
||||
[DnsmasqConfKeys.KeepInForeground] = "Do not daemonise; stay in foreground (e.g. under systemd).",
|
||||
[DnsmasqConfKeys.NoDaemon] = "Debug mode: no fork, no pid file, log to stderr.",
|
||||
[DnsmasqConfKeys.Conntrack] = "Linux connection-tracking mark for UBus/query filtering (platform-dependent).",
|
||||
[DnsmasqConfKeys.QuietDhcp] = "Suppress routine DHCP logging.",
|
||||
[DnsmasqConfKeys.QuietDhcp6] = "Suppress routine DHCPv6 logging.",
|
||||
[DnsmasqConfKeys.QuietRa] = "Suppress routine router advertisement logging.",
|
||||
[DnsmasqConfKeys.QuietTftp] = "Suppress routine TFTP logging.",
|
||||
}.ToFrozenDictionary();
|
||||
|
||||
/// <summary>Returns a short tooltip for the option, or null if none is defined.</summary>
|
||||
|
||||
@@ -87,6 +87,11 @@ public static class EffectiveConfigFieldBuilder
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.FastDnsRetry, status, s => Config(s)?.FastDnsRetry, s => Sources(s)?.FastDnsRetry, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.Ipset, status, null, null, Items(ec => ec?.IpsetValues, src => src?.IpsetValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.Nftset, status, null, null, Items(ec => ec?.NftsetValues, src => src?.NftsetValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.ConnmarkAllowlistEnable, status, s => Config(s)?.ConnmarkAllowlistEnable, s => Sources(s)?.ConnmarkAllowlistEnable, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.NoRoundRobin, status, s => Config(s)?.NoRoundRobin, s => Sources(s)?.NoRoundRobin, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DnsForwardMax, status, s => Config(s)?.DnsForwardMax, s => Sources(s)?.DnsForwardMax, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.ConnmarkAllowlist, status, null, null, Items(ec => ec?.ConnmarkAllowlistValues, src => src?.ConnmarkAllowlistValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.Do0x20Encode, status, s => Config(s)?.Do0x20EncodeState, s => Sources(s)?.Do0x20Encode, null);
|
||||
|
||||
// DNS records
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.Domain, status, null, null, Items(ec => ec?.DomainValues, src => src?.DomainValues));
|
||||
@@ -99,6 +104,13 @@ public static class EffectiveConfigFieldBuilder
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.HostRecord, status, null, null, Items(ec => ec?.HostRecordValues, src => src?.HostRecordValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DynamicHost, status, null, null, Items(ec => ec?.DynamicHostValues, src => src?.DynamicHostValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.InterfaceName, status, null, null, Items(ec => ec?.InterfaceNameValues, src => src?.InterfaceNameValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.CaaRecord, status, null, null, Items(ec => ec?.CaaRecordValues, src => src?.CaaRecordValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DnsRr, status, null, null, Items(ec => ec?.DnsRrValues, src => src?.DnsRrValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.SynthDomain, status, null, null, Items(ec => ec?.SynthDomainValues, src => src?.SynthDomainValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.AuthZone, status, null, null, Items(ec => ec?.AuthZoneValues, src => src?.AuthZoneValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.AuthSoa, status, null, null, Items(ec => ec?.AuthSoaValues, src => src?.AuthSoaValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.AuthSecServers, status, null, null, Items(ec => ec?.AuthSecServersValues, src => src?.AuthSecServersValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.AuthPeer, status, null, null, Items(ec => ec?.AuthPeerValues, src => src?.AuthPeerValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.MxTarget, status, s => Config(s)?.MxTarget, s => Sources(s)?.MxTarget, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.Localmx, status, s => Config(s)?.Localmx, s => Sources(s)?.Localmx, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.Selfmx, status, s => Config(s)?.Selfmx, s => Sources(s)?.Selfmx, null);
|
||||
@@ -107,7 +119,21 @@ public static class EffectiveConfigFieldBuilder
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpAuthoritative, status, s => Config(s)?.DhcpAuthoritative, s => Sources(s)?.DhcpAuthoritative, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpRapidCommit, status, s => Config(s)?.DhcpRapidCommit, s => Sources(s)?.DhcpRapidCommit, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.LeasefileRo, status, s => Config(s)?.LeasefileRo, s => Sources(s)?.LeasefileRo, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.Leasequery, status, s => Config(s)?.Leasequery, s => Sources(s)?.Leasequery, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpGenerateNames, status, s => Config(s)?.DhcpGenerateNames, s => Sources(s)?.DhcpGenerateNames, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpBroadcast, status, s => Config(s)?.DhcpBroadcast, s => Sources(s)?.DhcpBroadcast, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpSequentialIp, status, s => Config(s)?.DhcpSequentialIp, s => Sources(s)?.DhcpSequentialIp, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpIgnoreClid, status, s => Config(s)?.DhcpIgnoreClid, s => Sources(s)?.DhcpIgnoreClid, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.BootpDynamic, status, s => Config(s)?.BootpDynamic, s => Sources(s)?.BootpDynamic, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.NoPing, status, s => Config(s)?.NoPing, s => Sources(s)?.NoPing, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.ScriptArp, status, s => Config(s)?.ScriptArp, s => Sources(s)?.ScriptArp, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.ScriptOnRenewal, status, s => Config(s)?.ScriptOnRenewal, s => Sources(s)?.ScriptOnRenewal, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpNoOverride, status, s => Config(s)?.DhcpNoOverride, s => Sources(s)?.DhcpNoOverride, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpScript, status, s => Config(s)?.DhcpScriptPath, s => Sources(s)?.DhcpScriptPath, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpAlternatePort, status, s => Config(s)?.DhcpAlternatePort, s => Sources(s)?.DhcpAlternatePort, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpDuid, status, s => Config(s)?.DhcpDuid, s => Sources(s)?.DhcpDuid, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpLuascript, status, s => Config(s)?.DhcpLuascriptPath, s => Sources(s)?.DhcpLuascriptPath, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpScriptuser, status, s => Config(s)?.DhcpScriptuser, s => Sources(s)?.DhcpScriptuser, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpLeasefile, status, s => Config(s)?.DhcpLeaseFilePath, s => Sources(s)?.DhcpLeaseFilePath, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpLeaseMax, status, s => Config(s)?.DhcpLeaseMax, s => Sources(s)?.DhcpLeaseMax, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpTtl, status, s => Config(s)?.DhcpTtl, s => Sources(s)?.DhcpTtl, null);
|
||||
@@ -122,6 +148,14 @@ public static class EffectiveConfigFieldBuilder
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpHostsfile, status, null, null, Items(ec => ec?.DhcpHostsfilePaths, src => src?.DhcpHostsfilePaths));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpOptsfile, status, null, null, Items(ec => ec?.DhcpOptsfilePaths, src => src?.DhcpOptsfilePaths));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpHostsdir, status, null, null, Items(ec => ec?.DhcpHostsdirPaths, src => src?.DhcpHostsdirPaths));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpRelay, status, null, null, Items(ec => ec?.DhcpRelayValues, src => src?.DhcpRelayValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpCircuitid, status, null, null, Items(ec => ec?.DhcpCircuitidValues, src => src?.DhcpCircuitidValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpRemoteid, status, null, null, Items(ec => ec?.DhcpRemoteidValues, src => src?.DhcpRemoteidValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpSubscrid, status, null, null, Items(ec => ec?.DhcpSubscridValues, src => src?.DhcpSubscridValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpProxy, status, null, null, Items(ec => ec?.DhcpProxyValues, src => src?.DhcpProxyValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.TagIf, status, null, null, Items(ec => ec?.TagIfValues, src => src?.TagIfValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.BridgeInterface, status, null, null, Items(ec => ec?.BridgeInterfaceValues, src => src?.BridgeInterfaceValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.SharedNetwork, status, null, null, Items(ec => ec?.SharedNetworkValues, src => src?.SharedNetworkValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpBoot, status, null, null, Items(ec => ec?.DhcpBootValues, src => src?.DhcpBootValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpIgnore, status, null, null, Items(ec => ec?.DhcpIgnoreValues, src => src?.DhcpIgnoreValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpVendorclass, status, null, null, Items(ec => ec?.DhcpVendorclassValues, src => src?.DhcpVendorclassValues));
|
||||
@@ -137,11 +171,18 @@ public static class EffectiveConfigFieldBuilder
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.TftpRoot, status, s => Config(s)?.TftpRootPath, s => Sources(s)?.TftpRootPath, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.PxePrompt, status, s => Config(s)?.PxePrompt, s => Sources(s)?.PxePrompt, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.PxeService, status, null, null, Items(ec => ec?.PxeServiceValues, src => src?.PxeServiceValues));
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpPxeVendor, status, s => Config(s)?.DhcpPxeVendor, s => Sources(s)?.DhcpPxeVendor, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DhcpOptionPxe, status, null, null, Items(ec => ec?.DhcpOptionPxeValues, src => src?.DhcpOptionPxeValues));
|
||||
|
||||
// DNSSEC
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.Dnssec, status, s => Config(s)?.Dnssec, s => Sources(s)?.Dnssec, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DnssecCheckUnsigned, status, s => Config(s)?.DnssecCheckUnsigned, s => Sources(s)?.DnssecCheckUnsigned, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DnssecNoTimecheck, status, s => Config(s)?.DnssecNoTimecheck, s => Sources(s)?.DnssecNoTimecheck, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DnssecDebug, status, s => Config(s)?.DnssecDebug, s => Sources(s)?.DnssecDebug, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.ProxyDnssec, status, s => Config(s)?.ProxyDnssec, s => Sources(s)?.ProxyDnssec, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.AddCpeId, status, s => Config(s)?.AddCpeId, s => Sources(s)?.AddCpeId, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DnssecTimestamp, status, s => Config(s)?.DnssecTimestamp, s => Sources(s)?.DnssecTimestamp, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.DnssecLimits, status, s => Config(s)?.DnssecLimits, s => Sources(s)?.DnssecLimits, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.TrustAnchor, status, null, null, Items(ec => ec?.TrustAnchorValues, src => src?.TrustAnchorValues));
|
||||
|
||||
// Cache
|
||||
@@ -149,6 +190,12 @@ public static class EffectiveConfigFieldBuilder
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.CacheSize, status, s => Config(s)?.CacheSize, s => Sources(s)?.CacheSize, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.LocalTtl, status, s => Config(s)?.LocalTtl, s => Sources(s)?.LocalTtl, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.NoNegcache, status, s => Config(s)?.NoNegcache, s => Sources(s)?.NoNegcache, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.Dumpfile, status, s => Config(s)?.DumpfilePath, s => Sources(s)?.DumpfilePath, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.Dumpmask, status, s => Config(s)?.Dumpmask, s => Sources(s)?.Dumpmask, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.UseStaleCache, status, s => Config(s)?.UseStaleCache, s => Sources(s)?.UseStaleCache, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.AddMac, status, s => Config(s)?.AddMac, s => Sources(s)?.AddMac, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.AddSubnet, status, s => Config(s)?.AddSubnet, s => Sources(s)?.AddSubnet, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.Umbrella, status, s => Config(s)?.Umbrella, s => Sources(s)?.Umbrella, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.NegTtl, status, s => Config(s)?.NegTtl, s => Sources(s)?.NegTtl, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.MaxTtl, status, s => Config(s)?.MaxTtl, s => Sources(s)?.MaxTtl, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.MaxCacheTtl, status, s => Config(s)?.MaxCacheTtl, s => Sources(s)?.MaxCacheTtl, null);
|
||||
@@ -179,6 +226,10 @@ public static class EffectiveConfigFieldBuilder
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.KeepInForeground, status, s => Config(s)?.KeepInForeground, s => Sources(s)?.KeepInForeground, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.NoDaemon, status, s => Config(s)?.NoDaemon, s => Sources(s)?.NoDaemon, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.Conntrack, status, s => Config(s)?.Conntrack, s => Sources(s)?.Conntrack, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.QuietDhcp, status, s => Config(s)?.QuietDhcp, s => Sources(s)?.QuietDhcp, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.QuietDhcp6, status, s => Config(s)?.QuietDhcp6, s => Sources(s)?.QuietDhcp6, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.QuietRa, status, s => Config(s)?.QuietRa, s => Sources(s)?.QuietRa, null);
|
||||
list.AddDescriptor(registry, DnsmasqConfKeys.QuietTftp, status, s => Config(s)?.QuietTftp, s => Sources(s)?.QuietTftp, null);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -151,6 +151,57 @@ public static class EffectiveConfigOptionKindMap
|
||||
[DnsmasqConfKeys.KeepInForeground] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.NoDaemon] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.Conntrack] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.ConnmarkAllowlistEnable] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.NoRoundRobin] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.DnssecNoTimecheck] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.DnssecDebug] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.Leasequery] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.DhcpGenerateNames] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.DhcpBroadcast] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.DhcpSequentialIp] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.DhcpIgnoreClid] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.BootpDynamic] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.NoPing] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.ScriptArp] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.ScriptOnRenewal] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.DhcpNoOverride] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.QuietDhcp] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.QuietDhcp6] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.QuietRa] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.QuietTftp] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.DnsForwardMax] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.Dumpfile] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.Dumpmask] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.AddCpeId] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.DnssecTimestamp] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.DnssecLimits] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.DhcpAlternatePort] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.DhcpDuid] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.DhcpLuascript] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.DhcpScriptuser] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.DhcpPxeVendor] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.ConnmarkAllowlist] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.CaaRecord] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.DnsRr] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.SynthDomain] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.AuthZone] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.AuthSoa] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.AuthSecServers] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.AuthPeer] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.DhcpRelay] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.DhcpCircuitid] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.DhcpRemoteid] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.DhcpSubscrid] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.DhcpProxy] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.TagIf] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.BridgeInterface] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.SharedNetwork] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.DhcpOptionPxe] = EffectiveConfigFieldKind.Multi,
|
||||
[DnsmasqConfKeys.UseStaleCache] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.AddMac] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.AddSubnet] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.Umbrella] = EffectiveConfigFieldKind.Single,
|
||||
[DnsmasqConfKeys.Do0x20Encode] = EffectiveConfigFieldKind.Single,
|
||||
};
|
||||
|
||||
/// <summary>Returns Single or Multi for the given option name; defaults to Single if unknown.</summary>
|
||||
@@ -287,9 +338,107 @@ public static class EffectiveConfigParserBehaviorMap
|
||||
[DnsmasqConfKeys.KeepInForeground] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.NoDaemon] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.Conntrack] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.ConnmarkAllowlistEnable] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.NoRoundRobin] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.DnssecNoTimecheck] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.DnssecDebug] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.Leasequery] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.DhcpGenerateNames] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.DhcpBroadcast] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.DhcpSequentialIp] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.DhcpIgnoreClid] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.BootpDynamic] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.NoPing] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.ScriptArp] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.ScriptOnRenewal] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.DhcpNoOverride] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.QuietDhcp] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.QuietDhcp6] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.QuietRa] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.QuietTftp] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.DnsForwardMax] = EffectiveConfigParserBehavior.LastWins,
|
||||
[DnsmasqConfKeys.Dumpfile] = EffectiveConfigParserBehavior.LastWins,
|
||||
[DnsmasqConfKeys.Dumpmask] = EffectiveConfigParserBehavior.LastWins,
|
||||
[DnsmasqConfKeys.AddCpeId] = EffectiveConfigParserBehavior.LastWins,
|
||||
[DnsmasqConfKeys.DnssecTimestamp] = EffectiveConfigParserBehavior.LastWins,
|
||||
[DnsmasqConfKeys.DnssecLimits] = EffectiveConfigParserBehavior.LastWins,
|
||||
[DnsmasqConfKeys.DhcpAlternatePort] = EffectiveConfigParserBehavior.LastWins,
|
||||
[DnsmasqConfKeys.DhcpDuid] = EffectiveConfigParserBehavior.LastWins,
|
||||
[DnsmasqConfKeys.DhcpLuascript] = EffectiveConfigParserBehavior.LastWins,
|
||||
[DnsmasqConfKeys.DhcpScriptuser] = EffectiveConfigParserBehavior.LastWins,
|
||||
[DnsmasqConfKeys.DhcpPxeVendor] = EffectiveConfigParserBehavior.LastWins,
|
||||
[DnsmasqConfKeys.ConnmarkAllowlist] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.CaaRecord] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.DnsRr] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.SynthDomain] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.AuthZone] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.AuthSoa] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.AuthSecServers] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.AuthPeer] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.DhcpRelay] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.DhcpCircuitid] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.DhcpRemoteid] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.DhcpSubscrid] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.DhcpProxy] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.TagIf] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.BridgeInterface] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.SharedNetwork] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.DhcpOptionPxe] = EffectiveConfigParserBehavior.Multi,
|
||||
[DnsmasqConfKeys.UseStaleCache] = EffectiveConfigParserBehavior.LastWins,
|
||||
[DnsmasqConfKeys.AddMac] = EffectiveConfigParserBehavior.LastWins,
|
||||
[DnsmasqConfKeys.AddSubnet] = EffectiveConfigParserBehavior.LastWins,
|
||||
[DnsmasqConfKeys.Umbrella] = EffectiveConfigParserBehavior.LastWins,
|
||||
[DnsmasqConfKeys.Do0x20Encode] = EffectiveConfigParserBehavior.Flag,
|
||||
[DnsmasqConfKeys.No0x20Encode] = EffectiveConfigParserBehavior.Flag,
|
||||
};
|
||||
|
||||
/// <summary>Returns LastWins, Flag, or Multi for the given option name; defaults to LastWins if unknown.</summary>
|
||||
public static EffectiveConfigParserBehavior GetBehavior(string optionName) =>
|
||||
BehaviorByOptionName.TryGetValue(optionName, out var b) ? b : EffectiveConfigParserBehavior.LastWins;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// How to serialize an option when writing the managed config file.
|
||||
/// Used by DnsmasqConfigService so KeyOnlyOrValue and InversePair options serialize correctly.
|
||||
/// </summary>
|
||||
public enum EffectiveConfigWriteBehavior
|
||||
{
|
||||
Flag,
|
||||
SingleValue,
|
||||
MultiValue,
|
||||
KeyOnlyOrValue,
|
||||
InversePair,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps dnsmasq option names to write behavior. Options not in the map default to SingleValue
|
||||
/// (or are inferred from parser behavior in the service). Add entries for KeyOnlyOrValue and InversePair options.
|
||||
/// </summary>
|
||||
public static class EffectiveConfigWriteBehaviorMap
|
||||
{
|
||||
private static readonly IReadOnlyDictionary<string, EffectiveConfigWriteBehavior> BehaviorByOptionName =
|
||||
new Dictionary<string, EffectiveConfigWriteBehavior>(StringComparer.Ordinal)
|
||||
{
|
||||
[DnsmasqConfKeys.Conntrack] = EffectiveConfigWriteBehavior.Flag,
|
||||
[DnsmasqConfKeys.UseStaleCache] = EffectiveConfigWriteBehavior.KeyOnlyOrValue,
|
||||
[DnsmasqConfKeys.AddMac] = EffectiveConfigWriteBehavior.KeyOnlyOrValue,
|
||||
[DnsmasqConfKeys.AddSubnet] = EffectiveConfigWriteBehavior.KeyOnlyOrValue,
|
||||
[DnsmasqConfKeys.Umbrella] = EffectiveConfigWriteBehavior.KeyOnlyOrValue,
|
||||
[DnsmasqConfKeys.Do0x20Encode] = EffectiveConfigWriteBehavior.InversePair,
|
||||
};
|
||||
|
||||
/// <summary>For InversePair options: (key for "enabled", key for "disabled"). Null if not an InversePair or unknown.</summary>
|
||||
private static readonly IReadOnlyDictionary<string, (string KeyA, string KeyB)> InversePairKeysByOptionName =
|
||||
new Dictionary<string, (string, string)>(StringComparer.Ordinal)
|
||||
{
|
||||
[DnsmasqConfKeys.Do0x20Encode] = (DnsmasqConfKeys.Do0x20Encode, DnsmasqConfKeys.No0x20Encode),
|
||||
};
|
||||
|
||||
/// <summary>Returns write behavior for the option; defaults to SingleValue if unknown.</summary>
|
||||
public static EffectiveConfigWriteBehavior GetBehavior(string optionName) =>
|
||||
BehaviorByOptionName.TryGetValue(optionName, out var b) ? b : EffectiveConfigWriteBehavior.SingleValue;
|
||||
|
||||
/// <summary>Returns the pair of config keys (enabled, disabled) for an InversePair option; null otherwise.</summary>
|
||||
public static (string KeyA, string KeyB)? GetInversePairKeys(string optionName) =>
|
||||
InversePairKeysByOptionName.TryGetValue(optionName, out var pair) ? pair : null;
|
||||
}
|
||||
|
||||
@@ -67,6 +67,11 @@ public static class EffectiveConfigSections
|
||||
DnsmasqConfKeys.FastDnsRetry,
|
||||
DnsmasqConfKeys.Ipset,
|
||||
DnsmasqConfKeys.Nftset,
|
||||
DnsmasqConfKeys.ConnmarkAllowlistEnable,
|
||||
DnsmasqConfKeys.NoRoundRobin,
|
||||
DnsmasqConfKeys.DnsForwardMax,
|
||||
DnsmasqConfKeys.ConnmarkAllowlist,
|
||||
DnsmasqConfKeys.Do0x20Encode,
|
||||
]),
|
||||
new SectionDef(SectionDnsRecords, "DNS records", [
|
||||
DnsmasqConfKeys.Domain,
|
||||
@@ -79,6 +84,13 @@ public static class EffectiveConfigSections
|
||||
DnsmasqConfKeys.HostRecord,
|
||||
DnsmasqConfKeys.DynamicHost,
|
||||
DnsmasqConfKeys.InterfaceName,
|
||||
DnsmasqConfKeys.CaaRecord,
|
||||
DnsmasqConfKeys.DnsRr,
|
||||
DnsmasqConfKeys.SynthDomain,
|
||||
DnsmasqConfKeys.AuthZone,
|
||||
DnsmasqConfKeys.AuthSoa,
|
||||
DnsmasqConfKeys.AuthSecServers,
|
||||
DnsmasqConfKeys.AuthPeer,
|
||||
DnsmasqConfKeys.MxTarget,
|
||||
DnsmasqConfKeys.Localmx,
|
||||
DnsmasqConfKeys.Selfmx,
|
||||
@@ -87,7 +99,21 @@ public static class EffectiveConfigSections
|
||||
DnsmasqConfKeys.DhcpAuthoritative,
|
||||
DnsmasqConfKeys.DhcpRapidCommit,
|
||||
DnsmasqConfKeys.LeasefileRo,
|
||||
DnsmasqConfKeys.Leasequery,
|
||||
DnsmasqConfKeys.DhcpGenerateNames,
|
||||
DnsmasqConfKeys.DhcpBroadcast,
|
||||
DnsmasqConfKeys.DhcpSequentialIp,
|
||||
DnsmasqConfKeys.DhcpIgnoreClid,
|
||||
DnsmasqConfKeys.BootpDynamic,
|
||||
DnsmasqConfKeys.NoPing,
|
||||
DnsmasqConfKeys.ScriptArp,
|
||||
DnsmasqConfKeys.ScriptOnRenewal,
|
||||
DnsmasqConfKeys.DhcpNoOverride,
|
||||
DnsmasqConfKeys.DhcpScript,
|
||||
DnsmasqConfKeys.DhcpAlternatePort,
|
||||
DnsmasqConfKeys.DhcpDuid,
|
||||
DnsmasqConfKeys.DhcpLuascript,
|
||||
DnsmasqConfKeys.DhcpScriptuser,
|
||||
DnsmasqConfKeys.DhcpLeasefile,
|
||||
DnsmasqConfKeys.DhcpLeaseMax,
|
||||
DnsmasqConfKeys.DhcpTtl,
|
||||
@@ -106,6 +132,14 @@ public static class EffectiveConfigSections
|
||||
DnsmasqConfKeys.DhcpIgnore,
|
||||
DnsmasqConfKeys.DhcpVendorclass,
|
||||
DnsmasqConfKeys.DhcpUserclass,
|
||||
DnsmasqConfKeys.DhcpRelay,
|
||||
DnsmasqConfKeys.DhcpCircuitid,
|
||||
DnsmasqConfKeys.DhcpRemoteid,
|
||||
DnsmasqConfKeys.DhcpSubscrid,
|
||||
DnsmasqConfKeys.DhcpProxy,
|
||||
DnsmasqConfKeys.TagIf,
|
||||
DnsmasqConfKeys.BridgeInterface,
|
||||
DnsmasqConfKeys.SharedNetwork,
|
||||
DnsmasqConfKeys.RaParam,
|
||||
DnsmasqConfKeys.Slaac,
|
||||
]),
|
||||
@@ -117,11 +151,18 @@ public static class EffectiveConfigSections
|
||||
DnsmasqConfKeys.TftpRoot,
|
||||
DnsmasqConfKeys.PxePrompt,
|
||||
DnsmasqConfKeys.PxeService,
|
||||
DnsmasqConfKeys.DhcpPxeVendor,
|
||||
DnsmasqConfKeys.DhcpOptionPxe,
|
||||
]),
|
||||
new SectionDef(SectionDnssec, "DNSSEC", [
|
||||
DnsmasqConfKeys.Dnssec,
|
||||
DnsmasqConfKeys.DnssecCheckUnsigned,
|
||||
DnsmasqConfKeys.DnssecNoTimecheck,
|
||||
DnsmasqConfKeys.DnssecDebug,
|
||||
DnsmasqConfKeys.ProxyDnssec,
|
||||
DnsmasqConfKeys.AddCpeId,
|
||||
DnsmasqConfKeys.DnssecTimestamp,
|
||||
DnsmasqConfKeys.DnssecLimits,
|
||||
DnsmasqConfKeys.TrustAnchor,
|
||||
]),
|
||||
new SectionDef(SectionCache, "Cache", [
|
||||
@@ -133,6 +174,12 @@ public static class EffectiveConfigSections
|
||||
DnsmasqConfKeys.MaxTtl,
|
||||
DnsmasqConfKeys.MaxCacheTtl,
|
||||
DnsmasqConfKeys.MinCacheTtl,
|
||||
DnsmasqConfKeys.Dumpfile,
|
||||
DnsmasqConfKeys.Dumpmask,
|
||||
DnsmasqConfKeys.UseStaleCache,
|
||||
DnsmasqConfKeys.AddMac,
|
||||
DnsmasqConfKeys.AddSubnet,
|
||||
DnsmasqConfKeys.Umbrella,
|
||||
]),
|
||||
new SectionDef(SectionProcess, "Process & networking", [
|
||||
DnsmasqConfKeys.NoPoll,
|
||||
@@ -159,6 +206,10 @@ public static class EffectiveConfigSections
|
||||
DnsmasqConfKeys.KeepInForeground,
|
||||
DnsmasqConfKeys.NoDaemon,
|
||||
DnsmasqConfKeys.Conntrack,
|
||||
DnsmasqConfKeys.QuietDhcp,
|
||||
DnsmasqConfKeys.QuietDhcp6,
|
||||
DnsmasqConfKeys.QuietRa,
|
||||
DnsmasqConfKeys.QuietTftp,
|
||||
]),
|
||||
];
|
||||
|
||||
|
||||
@@ -293,6 +293,23 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
|
||||
var dhcpHostsfilePaths = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpHostsfile);
|
||||
var dhcpOptsfilePaths = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpOptsfile);
|
||||
var dhcpHostsdirPaths = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpHostsdir);
|
||||
var connmarkAllowlistValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.ConnmarkAllowlist);
|
||||
var caaRecordValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.CaaRecord);
|
||||
var dnsRrValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DnsRr);
|
||||
var synthDomainValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.SynthDomain);
|
||||
var authZoneValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.AuthZone);
|
||||
var authSoaValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.AuthSoa);
|
||||
var authSecServersValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.AuthSecServers);
|
||||
var authPeerValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.AuthPeer);
|
||||
var dhcpRelayValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpRelay);
|
||||
var dhcpCircuitidValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpCircuitid);
|
||||
var dhcpRemoteidValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpRemoteid);
|
||||
var dhcpSubscridValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpSubscrid);
|
||||
var dhcpProxyValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpProxy);
|
||||
var tagIfValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.TagIf);
|
||||
var bridgeInterfaceValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.BridgeInterface);
|
||||
var sharedNetworkValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.SharedNetwork);
|
||||
var dhcpOptionPxeValues = (IReadOnlyList<string>)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpOptionPxe);
|
||||
|
||||
var expandHosts = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.ExpandHosts);
|
||||
var bogusPriv = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.BogusPriv);
|
||||
@@ -330,6 +347,24 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
|
||||
var keepInForeground = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.KeepInForeground);
|
||||
var noDaemon = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.NoDaemon);
|
||||
var proxyDnssec = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.ProxyDnssec);
|
||||
var connmarkAllowlistEnable = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.ConnmarkAllowlistEnable);
|
||||
var noRoundRobin = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.NoRoundRobin);
|
||||
var dnssecNoTimecheck = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DnssecNoTimecheck);
|
||||
var dnssecDebug = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DnssecDebug);
|
||||
var leasequery = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.Leasequery);
|
||||
var dhcpGenerateNames = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpGenerateNames);
|
||||
var dhcpBroadcast = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpBroadcast);
|
||||
var dhcpSequentialIp = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpSequentialIp);
|
||||
var dhcpIgnoreClid = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpIgnoreClid);
|
||||
var bootpDynamic = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.BootpDynamic);
|
||||
var noPing = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.NoPing);
|
||||
var scriptArp = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.ScriptArp);
|
||||
var scriptOnRenewal = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.ScriptOnRenewal);
|
||||
var dhcpNoOverride = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpNoOverride);
|
||||
var quietDhcp = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.QuietDhcp);
|
||||
var quietDhcp6 = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.QuietDhcp6);
|
||||
var quietRa = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.QuietRa);
|
||||
var quietTftp = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.QuietTftp);
|
||||
|
||||
var dhcpLeaseFilePath = DnsmasqConfIncludeParser.GetDhcpLeaseFilePathFromConfigFiles(paths, pathToLines);
|
||||
|
||||
@@ -391,6 +426,39 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
|
||||
var dhcpScriptPath = string.IsNullOrWhiteSpace(dhcpScriptVal) ? null : DnsmasqConfIncludeParser.ResolvePath(dhcpScriptVal?.Trim(), dhcpScriptDir);
|
||||
var (mxTargetVal, _) = ((string?, string?))ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.MxTarget);
|
||||
var mxTarget = string.IsNullOrWhiteSpace(mxTargetVal) ? null : mxTargetVal.Trim();
|
||||
var (dnsForwardMaxVal, _) = ((string?, string?))ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DnsForwardMax);
|
||||
var dnsForwardMax = TryParseInt(dnsForwardMaxVal);
|
||||
var (dumpfileVal, dumpfileDir) = ((string?, string?))ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.Dumpfile);
|
||||
var dumpfilePath = string.IsNullOrWhiteSpace(dumpfileVal) ? null : DnsmasqConfIncludeParser.ResolvePath(dumpfileVal.Trim(), dumpfileDir);
|
||||
var (dumpmaskVal, _) = ((string?, string?))ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.Dumpmask);
|
||||
var dumpmask = string.IsNullOrWhiteSpace(dumpmaskVal) ? null : dumpmaskVal.Trim();
|
||||
var (addCpeIdVal, _) = ((string?, string?))ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.AddCpeId);
|
||||
var addCpeId = string.IsNullOrWhiteSpace(addCpeIdVal) ? null : addCpeIdVal.Trim();
|
||||
var (dnssecTimestampVal, _) = ((string?, string?))ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DnssecTimestamp);
|
||||
var dnssecTimestamp = string.IsNullOrWhiteSpace(dnssecTimestampVal) ? null : dnssecTimestampVal.Trim();
|
||||
var (dnssecLimitsVal, _) = ((string?, string?))ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DnssecLimits);
|
||||
var dnssecLimits = string.IsNullOrWhiteSpace(dnssecLimitsVal) ? null : dnssecLimitsVal.Trim();
|
||||
var (dhcpAlternatePortVal, _) = ((string?, string?))ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpAlternatePort);
|
||||
var dhcpAlternatePort = string.IsNullOrWhiteSpace(dhcpAlternatePortVal) ? null : dhcpAlternatePortVal.Trim();
|
||||
var (dhcpDuidVal, _) = ((string?, string?))ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpDuid);
|
||||
var dhcpDuid = string.IsNullOrWhiteSpace(dhcpDuidVal) ? null : dhcpDuidVal.Trim();
|
||||
var (dhcpLuascriptVal, dhcpLuascriptDir) = ((string?, string?))ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpLuascript);
|
||||
var dhcpLuascriptPath = string.IsNullOrWhiteSpace(dhcpLuascriptVal) ? null : DnsmasqConfIncludeParser.ResolvePath(dhcpLuascriptVal?.Trim(), dhcpLuascriptDir);
|
||||
var (dhcpScriptuserVal, _) = ((string?, string?))ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpScriptuser);
|
||||
var dhcpScriptuser = string.IsNullOrWhiteSpace(dhcpScriptuserVal) ? null : dhcpScriptuserVal.Trim();
|
||||
var (dhcpPxeVendorVal, _) = ((string?, string?))ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.DhcpPxeVendor);
|
||||
var dhcpPxeVendor = string.IsNullOrWhiteSpace(dhcpPxeVendorVal) ? null : dhcpPxeVendorVal.Trim();
|
||||
var (useStaleCacheVal, _) = ((string?, string?))ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.UseStaleCache);
|
||||
var useStaleCache = useStaleCacheVal == null ? null : (string.IsNullOrWhiteSpace(useStaleCacheVal) ? "" : useStaleCacheVal.Trim());
|
||||
var (addMacVal, _) = ((string?, string?))ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.AddMac);
|
||||
var addMac = addMacVal == null ? null : (string.IsNullOrWhiteSpace(addMacVal) ? "" : addMacVal.Trim());
|
||||
var (addSubnetVal, _) = ((string?, string?))ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.AddSubnet);
|
||||
var addSubnet = addSubnetVal == null ? null : (string.IsNullOrWhiteSpace(addSubnetVal) ? "" : addSubnetVal.Trim());
|
||||
var (umbrellaVal, _) = ((string?, string?))ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.Umbrella);
|
||||
var umbrella = umbrellaVal == null ? null : (string.IsNullOrWhiteSpace(umbrellaVal) ? "" : umbrellaVal.Trim());
|
||||
var do0x20 = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.Do0x20Encode);
|
||||
var no0x20 = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.No0x20Encode);
|
||||
var do0x20EncodeState = do0x20 ? ExplicitToggleState.Enabled : (no0x20 ? ExplicitToggleState.Disabled : ExplicitToggleState.Default);
|
||||
var conntrack = (bool)ParseOptionValue(paths, pathToLines, DnsmasqConfKeys.Conntrack);
|
||||
|
||||
return new EffectiveDnsmasqConfig(
|
||||
@@ -401,14 +469,18 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
|
||||
domainValues, cnameValues, mxHostValues, srvValues, ptrRecordValues, txtRecordValues, naptrRecordValues, hostRecordValues, dynamicHostValues, interfaceNameValues,
|
||||
dhcpOptionForceLines, ipsetValues, nftsetValues, dhcpMacValues, dhcpNameMatchValues, dhcpIgnoreNamesValues,
|
||||
dhcpHostsfilePaths, dhcpOptsfilePaths, dhcpHostsdirPaths,
|
||||
connmarkAllowlistValues, caaRecordValues, dnsRrValues, synthDomainValues, authZoneValues, authSoaValues, authSecServersValues, authPeerValues,
|
||||
dhcpRelayValues, dhcpCircuitidValues, dhcpRemoteidValues, dhcpSubscridValues, dhcpProxyValues, tagIfValues, bridgeInterfaceValues, sharedNetworkValues, dhcpOptionPxeValues,
|
||||
expandHosts, bogusPriv, strictOrder, allServers, noResolv, domainNeeded, noPoll, bindInterfaces, bindDynamic, noNegcache,
|
||||
dnsLoopDetect, stopDnsRebind, rebindLocalhostOk, clearOnReload, filterwin2k, filterA, filterAaaa, localiseQueries, logDebug, dhcpAuthoritative, leasefileRo,
|
||||
enableTftp, tftpSecure, tftpNoFail, tftpNoBlocksize, dnssec, dnssecCheckUnsigned, readEthers, dhcpRapidCommit, localmx, selfmx, enableRa, logDhcp,
|
||||
keepInForeground, noDaemon, proxyDnssec,
|
||||
connmarkAllowlistEnable, noRoundRobin, dnssecNoTimecheck, dnssecDebug, leasequery, dhcpGenerateNames, dhcpBroadcast, dhcpSequentialIp, dhcpIgnoreClid, bootpDynamic, noPing, scriptArp, scriptOnRenewal, dhcpNoOverride, quietDhcp, quietDhcp6, quietRa, quietTftp,
|
||||
dhcpLeaseFilePath, cacheSize, port, localTtl, pidFilePath, user, group, logFacility, logQueries,
|
||||
authTtl, ednsPacketMax, queryPort, portLimit, minPort, maxPort, logAsync, localService, dhcpLeaseMax,
|
||||
negTtl, maxTtl, maxCacheTtl, minCacheTtl, dhcpTtl, tftpRootPath, pxePrompt, enableDbus, enableUbus, fastDnsRetry,
|
||||
dhcpScriptPath, mxTarget, conntrack
|
||||
dhcpScriptPath, mxTarget, dnsForwardMax, dumpfilePath, dumpmask, addCpeId, dnssecTimestamp, dnssecLimits, dhcpAlternatePort, dhcpDuid, dhcpLuascriptPath, dhcpScriptuser, dhcpPxeVendor,
|
||||
useStaleCache, addMac, addSubnet, umbrella, do0x20EncodeState, conntrack
|
||||
);
|
||||
}
|
||||
|
||||
@@ -466,6 +538,23 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
|
||||
var dhcpHostsfileWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpHostsfile, managedFilePath);
|
||||
var dhcpOptsfileWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpOptsfile, managedFilePath);
|
||||
var dhcpHostsdirWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpHostsdir, managedFilePath);
|
||||
var connmarkAllowlistWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.ConnmarkAllowlist, managedFilePath);
|
||||
var caaRecordWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.CaaRecord, managedFilePath);
|
||||
var dnsRrWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DnsRr, managedFilePath);
|
||||
var synthDomainWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.SynthDomain, managedFilePath);
|
||||
var authZoneWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.AuthZone, managedFilePath);
|
||||
var authSoaWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.AuthSoa, managedFilePath);
|
||||
var authSecServersWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.AuthSecServers, managedFilePath);
|
||||
var authPeerWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.AuthPeer, managedFilePath);
|
||||
var dhcpRelayWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpRelay, managedFilePath);
|
||||
var dhcpCircuitidWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpCircuitid, managedFilePath);
|
||||
var dhcpRemoteidWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpRemoteid, managedFilePath);
|
||||
var dhcpSubscridWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpSubscrid, managedFilePath);
|
||||
var dhcpProxyWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpProxy, managedFilePath);
|
||||
var tagIfWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.TagIf, managedFilePath);
|
||||
var bridgeInterfaceWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.BridgeInterface, managedFilePath);
|
||||
var sharedNetworkWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.SharedNetwork, managedFilePath);
|
||||
var dhcpOptionPxeWithSource = (IReadOnlyList<(string Value, ConfigValueSource Source)>)ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpOptionPxe, managedFilePath);
|
||||
|
||||
var (_, expandHostsSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.ExpandHosts, managedFilePath);
|
||||
var (_, bogusPrivSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.BogusPriv, managedFilePath);
|
||||
@@ -503,6 +592,24 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
|
||||
var (_, keepInForegroundSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.KeepInForeground, managedFilePath);
|
||||
var (_, noDaemonSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.NoDaemon, managedFilePath);
|
||||
var (_, proxyDnssecSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.ProxyDnssec, managedFilePath);
|
||||
var (_, connmarkAllowlistEnableSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.ConnmarkAllowlistEnable, managedFilePath);
|
||||
var (_, noRoundRobinSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.NoRoundRobin, managedFilePath);
|
||||
var (_, dnssecNoTimecheckSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DnssecNoTimecheck, managedFilePath);
|
||||
var (_, dnssecDebugSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DnssecDebug, managedFilePath);
|
||||
var (_, leasequerySource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.Leasequery, managedFilePath);
|
||||
var (_, dhcpGenerateNamesSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpGenerateNames, managedFilePath);
|
||||
var (_, dhcpBroadcastSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpBroadcast, managedFilePath);
|
||||
var (_, dhcpSequentialIpSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpSequentialIp, managedFilePath);
|
||||
var (_, dhcpIgnoreClidSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpIgnoreClid, managedFilePath);
|
||||
var (_, bootpDynamicSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.BootpDynamic, managedFilePath);
|
||||
var (_, noPingSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.NoPing, managedFilePath);
|
||||
var (_, scriptArpSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.ScriptArp, managedFilePath);
|
||||
var (_, scriptOnRenewalSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.ScriptOnRenewal, managedFilePath);
|
||||
var (_, dhcpNoOverrideSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpNoOverride, managedFilePath);
|
||||
var (_, quietDhcpSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.QuietDhcp, managedFilePath);
|
||||
var (_, quietDhcp6Source) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.QuietDhcp6, managedFilePath);
|
||||
var (_, quietRaSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.QuietRa, managedFilePath);
|
||||
var (_, quietTftpSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.QuietTftp, managedFilePath);
|
||||
|
||||
var (_, dhcpLeaseFilePathSource) = DnsmasqConfIncludeParser.GetDhcpLeaseFilePathFromConfigFilesWithSource(paths, pathToLines, managedFilePath);
|
||||
var (_, cacheSizeSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.CacheSize, managedFilePath);
|
||||
@@ -534,6 +641,24 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
|
||||
var (_, fastDnsRetrySource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.FastDnsRetry, managedFilePath);
|
||||
var (_, dhcpScriptPathSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpScript, managedFilePath);
|
||||
var (_, mxTargetSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.MxTarget, managedFilePath);
|
||||
var (_, dnsForwardMaxSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DnsForwardMax, managedFilePath);
|
||||
var (_, dumpfilePathSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.Dumpfile, managedFilePath);
|
||||
var (_, dumpmaskSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.Dumpmask, managedFilePath);
|
||||
var (_, addCpeIdSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.AddCpeId, managedFilePath);
|
||||
var (_, dnssecTimestampSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DnssecTimestamp, managedFilePath);
|
||||
var (_, dnssecLimitsSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DnssecLimits, managedFilePath);
|
||||
var (_, dhcpAlternatePortSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpAlternatePort, managedFilePath);
|
||||
var (_, dhcpDuidSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpDuid, managedFilePath);
|
||||
var (_, dhcpLuascriptPathSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpLuascript, managedFilePath);
|
||||
var (_, dhcpScriptuserSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpScriptuser, managedFilePath);
|
||||
var (_, dhcpPxeVendorSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpPxeVendor, managedFilePath);
|
||||
var (_, useStaleCacheSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.UseStaleCache, managedFilePath);
|
||||
var (_, addMacSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.AddMac, managedFilePath);
|
||||
var (_, addSubnetSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.AddSubnet, managedFilePath);
|
||||
var (_, umbrellaSource) = ((string?, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.Umbrella, managedFilePath);
|
||||
var (do0x20Set, do0x20EncodeSourceA) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.Do0x20Encode, managedFilePath);
|
||||
var (no0x20Set, no0x20EncodeSourceB) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.No0x20Encode, managedFilePath);
|
||||
var do0x20EncodeSource = do0x20Set ? do0x20EncodeSourceA : (no0x20Set ? no0x20EncodeSourceB : null);
|
||||
var (_, conntrackSource) = ((bool, ConfigValueSource?))ParseOptionWithSource(paths, pathToLines, DnsmasqConfKeys.Conntrack, managedFilePath);
|
||||
|
||||
return new EffectiveConfigSources(
|
||||
@@ -587,6 +712,23 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
|
||||
dhcpHostsfileWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
dhcpOptsfileWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
dhcpHostsdirWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
connmarkAllowlistWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
caaRecordWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
dnsRrWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
synthDomainWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
authZoneWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
authSoaWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
authSecServersWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
authPeerWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
dhcpRelayWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
dhcpCircuitidWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
dhcpRemoteidWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
dhcpSubscridWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
dhcpProxyWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
tagIfWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
bridgeInterfaceWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
sharedNetworkWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
dhcpOptionPxeWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
|
||||
expandHostsSource,
|
||||
bogusPrivSource,
|
||||
strictOrderSource,
|
||||
@@ -623,6 +765,24 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
|
||||
keepInForegroundSource,
|
||||
noDaemonSource,
|
||||
proxyDnssecSource,
|
||||
connmarkAllowlistEnableSource,
|
||||
noRoundRobinSource,
|
||||
dnssecNoTimecheckSource,
|
||||
dnssecDebugSource,
|
||||
leasequerySource,
|
||||
dhcpGenerateNamesSource,
|
||||
dhcpBroadcastSource,
|
||||
dhcpSequentialIpSource,
|
||||
dhcpIgnoreClidSource,
|
||||
bootpDynamicSource,
|
||||
noPingSource,
|
||||
scriptArpSource,
|
||||
scriptOnRenewalSource,
|
||||
dhcpNoOverrideSource,
|
||||
quietDhcpSource,
|
||||
quietDhcp6Source,
|
||||
quietRaSource,
|
||||
quietTftpSource,
|
||||
dhcpLeaseFilePathSource,
|
||||
cacheSizeSource,
|
||||
portSource,
|
||||
@@ -653,6 +813,22 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
|
||||
fastDnsRetrySource,
|
||||
dhcpScriptPathSource,
|
||||
mxTargetSource,
|
||||
dnsForwardMaxSource,
|
||||
dumpfilePathSource,
|
||||
dumpmaskSource,
|
||||
addCpeIdSource,
|
||||
dnssecTimestampSource,
|
||||
dnssecLimitsSource,
|
||||
dhcpAlternatePortSource,
|
||||
dhcpDuidSource,
|
||||
dhcpLuascriptPathSource,
|
||||
dhcpScriptuserSource,
|
||||
dhcpPxeVendorSource,
|
||||
useStaleCacheSource,
|
||||
addMacSource,
|
||||
addSubnetSource,
|
||||
umbrellaSource,
|
||||
do0x20EncodeSource,
|
||||
conntrackSource
|
||||
);
|
||||
}
|
||||
@@ -707,17 +883,23 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
|
||||
DhcpOptionForceLines: Array.Empty<string>(), IpsetValues: Array.Empty<string>(), NftsetValues: Array.Empty<string>(),
|
||||
DhcpMacValues: Array.Empty<string>(), DhcpNameMatchValues: Array.Empty<string>(), DhcpIgnoreNamesValues: Array.Empty<string>(),
|
||||
DhcpHostsfilePaths: Array.Empty<string>(), DhcpOptsfilePaths: Array.Empty<string>(), DhcpHostsdirPaths: Array.Empty<string>(),
|
||||
ConnmarkAllowlistValues: Array.Empty<string>(), CaaRecordValues: Array.Empty<string>(), DnsRrValues: Array.Empty<string>(), SynthDomainValues: Array.Empty<string>(),
|
||||
AuthZoneValues: Array.Empty<string>(), AuthSoaValues: Array.Empty<string>(), AuthSecServersValues: Array.Empty<string>(), AuthPeerValues: Array.Empty<string>(),
|
||||
DhcpRelayValues: Array.Empty<string>(), DhcpCircuitidValues: Array.Empty<string>(), DhcpRemoteidValues: Array.Empty<string>(), DhcpSubscridValues: Array.Empty<string>(), DhcpProxyValues: Array.Empty<string>(),
|
||||
TagIfValues: Array.Empty<string>(), BridgeInterfaceValues: Array.Empty<string>(), SharedNetworkValues: Array.Empty<string>(), DhcpOptionPxeValues: Array.Empty<string>(),
|
||||
ExpandHosts: false, BogusPriv: false, StrictOrder: false, AllServers: false, NoResolv: false, DomainNeeded: false, NoPoll: false,
|
||||
BindInterfaces: false, BindDynamic: false, NoNegcache: false, DnsLoopDetect: false, StopDnsRebind: false, RebindLocalhostOk: false, ClearOnReload: false,
|
||||
Filterwin2k: false, FilterA: false, FilterAaaa: false, LocaliseQueries: false, LogDebug: false, DhcpAuthoritative: false, LeasefileRo: false,
|
||||
EnableTftp: false, TftpSecure: false, TftpNoFail: false, TftpNoBlocksize: false, Dnssec: false, DnssecCheckUnsigned: false,
|
||||
ReadEthers: false, DhcpRapidCommit: false, Localmx: false, Selfmx: false, EnableRa: false, LogDhcp: false,
|
||||
KeepInForeground: false, NoDaemon: false, ProxyDnssec: false,
|
||||
ConnmarkAllowlistEnable: false, NoRoundRobin: false, DnssecNoTimecheck: false, DnssecDebug: false, Leasequery: false, DhcpGenerateNames: false, DhcpBroadcast: false, DhcpSequentialIp: false, DhcpIgnoreClid: false, BootpDynamic: false, NoPing: false, ScriptArp: false, ScriptOnRenewal: false, DhcpNoOverride: false, QuietDhcp: false, QuietDhcp6: false, QuietRa: false, QuietTftp: false,
|
||||
DhcpLeaseFilePath: null, CacheSize: null, Port: null, LocalTtl: null, PidFilePath: null, User: null, Group: null,
|
||||
LogFacility: null, LogQueries: null, AuthTtl: null, EdnsPacketMax: null, QueryPort: null, PortLimit: null, MinPort: null, MaxPort: null, LogAsync: null, LocalService: null,
|
||||
DhcpLeaseMax: null, NegTtl: null, MaxTtl: null, MaxCacheTtl: null, MinCacheTtl: null, DhcpTtl: null,
|
||||
TftpRootPath: null, PxePrompt: null, EnableDbus: null, EnableUbus: null, FastDnsRetry: null,
|
||||
DhcpScriptPath: null, MxTarget: null, Conntrack: false
|
||||
DhcpScriptPath: null, MxTarget: null, DnsForwardMax: null, DumpfilePath: null, Dumpmask: null, AddCpeId: null, DnssecTimestamp: null, DnssecLimits: null, DhcpAlternatePort: null, DhcpDuid: null, DhcpLuascriptPath: null, DhcpScriptuser: null, DhcpPxeVendor: null,
|
||||
UseStaleCache: null, AddMac: null, AddSubnet: null, Umbrella: null, Do0x20EncodeState: ExplicitToggleState.Default, Conntrack: false
|
||||
);
|
||||
|
||||
private static EffectiveConfigSources CreateDefaultEffectiveConfigSources() =>
|
||||
@@ -742,17 +924,23 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
|
||||
DhcpOptionForceLines: Array.Empty<ValueWithSource>(), IpsetValues: Array.Empty<ValueWithSource>(), NftsetValues: Array.Empty<ValueWithSource>(),
|
||||
DhcpMacValues: Array.Empty<ValueWithSource>(), DhcpNameMatchValues: Array.Empty<ValueWithSource>(), DhcpIgnoreNamesValues: Array.Empty<ValueWithSource>(),
|
||||
DhcpHostsfilePaths: Array.Empty<ValueWithSource>(), DhcpOptsfilePaths: Array.Empty<ValueWithSource>(), DhcpHostsdirPaths: Array.Empty<ValueWithSource>(),
|
||||
ConnmarkAllowlistValues: Array.Empty<ValueWithSource>(), CaaRecordValues: Array.Empty<ValueWithSource>(), DnsRrValues: Array.Empty<ValueWithSource>(), SynthDomainValues: Array.Empty<ValueWithSource>(),
|
||||
AuthZoneValues: Array.Empty<ValueWithSource>(), AuthSoaValues: Array.Empty<ValueWithSource>(), AuthSecServersValues: Array.Empty<ValueWithSource>(), AuthPeerValues: Array.Empty<ValueWithSource>(),
|
||||
DhcpRelayValues: Array.Empty<ValueWithSource>(), DhcpCircuitidValues: Array.Empty<ValueWithSource>(), DhcpRemoteidValues: Array.Empty<ValueWithSource>(), DhcpSubscridValues: Array.Empty<ValueWithSource>(), DhcpProxyValues: Array.Empty<ValueWithSource>(),
|
||||
TagIfValues: Array.Empty<ValueWithSource>(), BridgeInterfaceValues: Array.Empty<ValueWithSource>(), SharedNetworkValues: Array.Empty<ValueWithSource>(), DhcpOptionPxeValues: Array.Empty<ValueWithSource>(),
|
||||
ExpandHosts: null, BogusPriv: null, StrictOrder: null, AllServers: null, NoResolv: null, DomainNeeded: null, NoPoll: null,
|
||||
BindInterfaces: null, BindDynamic: null, NoNegcache: null, DnsLoopDetect: null, StopDnsRebind: null, RebindLocalhostOk: null, ClearOnReload: null,
|
||||
Filterwin2k: null, FilterA: null, FilterAaaa: null, LocaliseQueries: null, LogDebug: null, DhcpAuthoritative: null, LeasefileRo: null,
|
||||
EnableTftp: null, TftpSecure: null, TftpNoFail: null, TftpNoBlocksize: null, Dnssec: null, DnssecCheckUnsigned: null,
|
||||
ReadEthers: null, DhcpRapidCommit: null, Localmx: null, Selfmx: null, EnableRa: null, LogDhcp: null,
|
||||
KeepInForeground: null, NoDaemon: null, ProxyDnssec: null,
|
||||
ConnmarkAllowlistEnable: null, NoRoundRobin: null, DnssecNoTimecheck: null, DnssecDebug: null, Leasequery: null, DhcpGenerateNames: null, DhcpBroadcast: null, DhcpSequentialIp: null, DhcpIgnoreClid: null, BootpDynamic: null, NoPing: null, ScriptArp: null, ScriptOnRenewal: null, DhcpNoOverride: null, QuietDhcp: null, QuietDhcp6: null, QuietRa: null, QuietTftp: null,
|
||||
DhcpLeaseFilePath: null, CacheSize: null, Port: null, LocalTtl: null, PidFilePath: null, User: null, Group: null,
|
||||
LogFacility: null, LogQueries: null, AuthTtl: null, EdnsPacketMax: null, QueryPort: null, PortLimit: null, MinPort: null, MaxPort: null, LogAsync: null, LocalService: null,
|
||||
DhcpLeaseMax: null, NegTtl: null, MaxTtl: null, MaxCacheTtl: null, MinCacheTtl: null, DhcpTtl: null,
|
||||
TftpRootPath: null, PxePrompt: null, EnableDbus: null, EnableUbus: null, FastDnsRetry: null,
|
||||
DhcpScriptPath: null, MxTarget: null, Conntrack: null
|
||||
DhcpScriptPath: null, MxTarget: null, DnsForwardMax: null, DumpfilePath: null, Dumpmask: null, AddCpeId: null, DnssecTimestamp: null, DnssecLimits: null, DhcpAlternatePort: null, DhcpDuid: null, DhcpLuascriptPath: null, DhcpScriptuser: null, DhcpPxeVendor: null,
|
||||
UseStaleCache: null, AddMac: null, AddSubnet: null, Umbrella: null, Do0x20Encode: null, Conntrack: null
|
||||
);
|
||||
|
||||
private static int? TryParseInt(string? value)
|
||||
|
||||
@@ -231,8 +231,7 @@ public class DnsmasqConfigService : IDnsmasqConfigService
|
||||
var maxLineNumber = list.Count > 0 ? list.Max(l => l.LineNumber) : 0;
|
||||
foreach (var c in changes)
|
||||
{
|
||||
var behavior = EffectiveConfigParserBehaviorMap.GetBehavior(c.OptionName);
|
||||
var isFlag = behavior == EffectiveConfigParserBehavior.Flag;
|
||||
var writeBehavior = EffectiveConfigWriteBehaviorMap.GetBehavior(c.OptionName);
|
||||
var confKey = c.OptionName;
|
||||
|
||||
bool MatchesOption(DnsmasqConfLine line)
|
||||
@@ -242,6 +241,43 @@ public class DnsmasqConfigService : IDnsmasqConfigService
|
||||
return kv != null && string.Equals(kv.Value.key, confKey, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
if (writeBehavior == EffectiveConfigWriteBehavior.KeyOnlyOrValue)
|
||||
{
|
||||
RemoveAllMatchingLines(list, MatchesOption);
|
||||
var value = c.NewValue as string;
|
||||
if (value is null)
|
||||
continue;
|
||||
var lineText = value.Length == 0 ? confKey : $"{confKey}={value.Trim()}";
|
||||
list.Add(new OtherLine { LineNumber = maxLineNumber + 1, RawLine = lineText });
|
||||
maxLineNumber++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (writeBehavior == EffectiveConfigWriteBehavior.InversePair)
|
||||
{
|
||||
var pair = EffectiveConfigWriteBehaviorMap.GetInversePairKeys(confKey);
|
||||
if (pair is null)
|
||||
continue;
|
||||
var (pairKeyA, pairKeyB) = pair.Value;
|
||||
bool MatchesPair(DnsmasqConfLine line)
|
||||
{
|
||||
var raw = DnsmasqConfFileLineParser.ToLine(line);
|
||||
var kv = DnsmasqConfDirectiveParser.TryParseKeyValue(raw);
|
||||
return kv != null && (string.Equals(kv.Value.key, pairKeyA, StringComparison.Ordinal) || string.Equals(kv.Value.key, pairKeyB, StringComparison.Ordinal));
|
||||
}
|
||||
RemoveAllMatchingLines(list, MatchesPair);
|
||||
if (c.NewValue is ExplicitToggleState state && state != ExplicitToggleState.Default)
|
||||
{
|
||||
var lineKey = state == ExplicitToggleState.Enabled ? pairKeyA : pairKeyB;
|
||||
list.Add(new OtherLine { LineNumber = maxLineNumber + 1, RawLine = lineKey });
|
||||
maxLineNumber++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
var behavior = EffectiveConfigParserBehaviorMap.GetBehavior(c.OptionName);
|
||||
var isFlag = behavior == EffectiveConfigParserBehavior.Flag;
|
||||
|
||||
if (behavior == EffectiveConfigParserBehavior.Multi && TryGetMultiValues(c.NewValue, out var values))
|
||||
{
|
||||
IReadOnlyList<string> readonlyValues = readonlyByOption.TryGetValue(confKey, out var listValues) ? listValues : Array.Empty<string>();
|
||||
@@ -299,6 +335,15 @@ public class DnsmasqConfigService : IDnsmasqConfigService
|
||||
await WriteManagedConfigAsync(list, ct);
|
||||
}
|
||||
|
||||
private static void RemoveAllMatchingLines(List<DnsmasqConfLine> list, Predicate<DnsmasqConfLine> match)
|
||||
{
|
||||
for (var i = list.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (match(list[i]))
|
||||
list.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Keeps only values that should be written to managed config by subtracting values provided by
|
||||
/// non-managed files (multiset subtraction, order preserved).
|
||||
|
||||
+45
@@ -34,6 +34,7 @@ public class EffectiveConfigRenderFragmentRegistry : IEffectiveConfigRenderFragm
|
||||
RegisterInteger(EffectiveConfigFieldBuilder.SectionResolver, DnsmasqConfKeys.PortLimit, max: 65535);
|
||||
RegisterInteger(EffectiveConfigFieldBuilder.SectionResolver, DnsmasqConfKeys.MinPort, min: 1, max: 65535);
|
||||
RegisterInteger(EffectiveConfigFieldBuilder.SectionResolver, DnsmasqConfKeys.MaxPort, min: 1, max: 65535);
|
||||
RegisterInteger(EffectiveConfigFieldBuilder.SectionResolver, DnsmasqConfKeys.DnsForwardMax, min: 1);
|
||||
RegisterInteger(EffectiveConfigFieldBuilder.SectionCache, DnsmasqConfKeys.CacheSize, min: 0);
|
||||
RegisterInteger(EffectiveConfigFieldBuilder.SectionCache, DnsmasqConfKeys.LocalTtl, unit: "seconds");
|
||||
RegisterInteger(EffectiveConfigFieldBuilder.SectionCache, DnsmasqConfKeys.NegTtl, unit: "seconds");
|
||||
@@ -82,6 +83,33 @@ public class EffectiveConfigRenderFragmentRegistry : IEffectiveConfigRenderFragm
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionProcess, DnsmasqConfKeys.NoDaemon);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionProcess, DnsmasqConfKeys.Conntrack);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionDnssec, DnsmasqConfKeys.ProxyDnssec);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionResolver, DnsmasqConfKeys.ConnmarkAllowlistEnable);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionResolver, DnsmasqConfKeys.NoRoundRobin);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionDnssec, DnsmasqConfKeys.DnssecNoTimecheck);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionDnssec, DnsmasqConfKeys.DnssecDebug);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.Leasequery);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpGenerateNames);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpBroadcast);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpSequentialIp);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpIgnoreClid);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.BootpDynamic);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.NoPing);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.ScriptArp);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.ScriptOnRenewal);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpNoOverride);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionProcess, DnsmasqConfKeys.QuietDhcp);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionProcess, DnsmasqConfKeys.QuietDhcp6);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionProcess, DnsmasqConfKeys.QuietRa);
|
||||
RegisterFlag(EffectiveConfigFieldBuilder.SectionProcess, DnsmasqConfKeys.QuietTftp);
|
||||
|
||||
// do-0x20-encode / no-0x20-encode: tri-state dropdown (Default / Enabled / Disabled).
|
||||
RegisterComponent(EffectiveConfigFieldBuilder.SectionResolver, DnsmasqConfKeys.Do0x20Encode, typeof(Do0x20EncodeDisplay));
|
||||
|
||||
// Key-only or key=value options: checkbox (On) + optional value input.
|
||||
RegisterComponent(EffectiveConfigFieldBuilder.SectionCache, DnsmasqConfKeys.UseStaleCache, typeof(KeyOnlyOrValueDisplay));
|
||||
RegisterComponent(EffectiveConfigFieldBuilder.SectionCache, DnsmasqConfKeys.AddMac, typeof(KeyOnlyOrValueDisplay));
|
||||
RegisterComponent(EffectiveConfigFieldBuilder.SectionCache, DnsmasqConfKeys.AddSubnet, typeof(KeyOnlyOrValueDisplay));
|
||||
RegisterComponent(EffectiveConfigFieldBuilder.SectionCache, DnsmasqConfKeys.Umbrella, typeof(KeyOnlyOrValueDisplay));
|
||||
|
||||
// log-queries: dropdown (Off / On / extra / proto / auth).
|
||||
RegisterComponent(EffectiveConfigFieldBuilder.SectionResolver, DnsmasqConfKeys.LogQueries, typeof(LogQueriesDisplay));
|
||||
@@ -113,6 +141,7 @@ public class EffectiveConfigRenderFragmentRegistry : IEffectiveConfigRenderFragm
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionResolver, DnsmasqConfKeys.FilterRr);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionResolver, DnsmasqConfKeys.Ipset);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionResolver, DnsmasqConfKeys.Nftset);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionResolver, DnsmasqConfKeys.ConnmarkAllowlist);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDnsRecords, DnsmasqConfKeys.Domain);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDnsRecords, DnsmasqConfKeys.Cname);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDnsRecords, DnsmasqConfKeys.MxHost);
|
||||
@@ -123,6 +152,13 @@ public class EffectiveConfigRenderFragmentRegistry : IEffectiveConfigRenderFragm
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDnsRecords, DnsmasqConfKeys.HostRecord);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDnsRecords, DnsmasqConfKeys.DynamicHost);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDnsRecords, DnsmasqConfKeys.InterfaceName);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDnsRecords, DnsmasqConfKeys.CaaRecord);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDnsRecords, DnsmasqConfKeys.DnsRr);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDnsRecords, DnsmasqConfKeys.SynthDomain);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDnsRecords, DnsmasqConfKeys.AuthZone);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDnsRecords, DnsmasqConfKeys.AuthSoa);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDnsRecords, DnsmasqConfKeys.AuthSecServers);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDnsRecords, DnsmasqConfKeys.AuthPeer);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpRange);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpHost);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpOption);
|
||||
@@ -134,6 +170,14 @@ public class EffectiveConfigRenderFragmentRegistry : IEffectiveConfigRenderFragm
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpHostsfile);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpOptsfile);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpHostsdir);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpRelay);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpCircuitid);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpRemoteid);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpSubscrid);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpProxy);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.TagIf);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.BridgeInterface);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.SharedNetwork);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpBoot);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpIgnore);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpVendorclass);
|
||||
@@ -141,6 +185,7 @@ public class EffectiveConfigRenderFragmentRegistry : IEffectiveConfigRenderFragm
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.RaParam);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.Slaac);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionTftpPxe, DnsmasqConfKeys.PxeService);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionTftpPxe, DnsmasqConfKeys.DhcpOptionPxe);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionDnssec, DnsmasqConfKeys.TrustAnchor);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionCache, DnsmasqConfKeys.CacheRr);
|
||||
RegisterMultiDescriptor(EffectiveConfigFieldBuilder.SectionProcess, DnsmasqConfKeys.Interface);
|
||||
|
||||
+42
-8
@@ -19,7 +19,7 @@ public static class EffectiveConfigCrossOptionEvaluator
|
||||
{
|
||||
var issues = new List<FieldIssue>();
|
||||
|
||||
var noResolv = GetEffectiveNoResolv(status, pending);
|
||||
var noResolv = GetEffectiveBool(status, pending, DnsmasqConfKeys.NoResolv, s => s?.EffectiveConfig?.NoResolv ?? false);
|
||||
var serverValues = GetEffectiveServerValues(status, pending);
|
||||
|
||||
// no-resolv set with no upstream servers: DNS may not work
|
||||
@@ -33,17 +33,51 @@ public static class EffectiveConfigCrossOptionEvaluator
|
||||
ItemIndex: null));
|
||||
}
|
||||
|
||||
// conntrack cannot be combined with query-port (dnsmasq man page)
|
||||
var conntrack = GetEffectiveBool(status, pending, DnsmasqConfKeys.Conntrack, s => s?.EffectiveConfig?.Conntrack ?? false);
|
||||
var queryPort = GetEffectiveInt(status, pending, DnsmasqConfKeys.QueryPort, s => s?.EffectiveConfig?.QueryPort);
|
||||
if (conntrack && queryPort is not null)
|
||||
{
|
||||
issues.Add(new FieldIssue(
|
||||
$"{EffectiveConfigSections.SectionResolver}:{DnsmasqConfKeys.QueryPort}",
|
||||
"query-port cannot be combined with conntrack.",
|
||||
FieldIssueSeverity.Error,
|
||||
null));
|
||||
}
|
||||
|
||||
return issues;
|
||||
}
|
||||
|
||||
private static bool GetEffectiveNoResolv(DnsmasqServiceStatus? status, IReadOnlyList<PendingEffectiveConfigChange> pending)
|
||||
private static bool GetEffectiveBool(
|
||||
DnsmasqServiceStatus? status,
|
||||
IReadOnlyList<PendingEffectiveConfigChange>? pending,
|
||||
string optionName,
|
||||
Func<DnsmasqServiceStatus?, bool> fromConfig)
|
||||
{
|
||||
var fromConfig = status?.EffectiveConfig?.NoResolv ?? false;
|
||||
var pendingChange = pending?.FirstOrDefault(c =>
|
||||
string.Equals(c.OptionName, DnsmasqConfKeys.NoResolv, StringComparison.Ordinal));
|
||||
if (pendingChange?.NewValue is bool b)
|
||||
return b;
|
||||
return fromConfig;
|
||||
var pendingChange = pending?.FirstOrDefault(c => string.Equals(c.OptionName, optionName, StringComparison.Ordinal));
|
||||
if (pendingChange != null)
|
||||
{
|
||||
if (pendingChange.NewValue is bool b)
|
||||
return b;
|
||||
return false; // pending change to clear or invalid; treat as off for cross-option purposes
|
||||
}
|
||||
return fromConfig(status);
|
||||
}
|
||||
|
||||
private static int? GetEffectiveInt(
|
||||
DnsmasqServiceStatus? status,
|
||||
IReadOnlyList<PendingEffectiveConfigChange>? pending,
|
||||
string optionName,
|
||||
Func<DnsmasqServiceStatus?, int?> fromConfig)
|
||||
{
|
||||
var pendingChange = pending?.FirstOrDefault(c => string.Equals(c.OptionName, optionName, StringComparison.Ordinal));
|
||||
if (pendingChange != null)
|
||||
{
|
||||
if (pendingChange.NewValue is int i)
|
||||
return i;
|
||||
return null; // pending change to clear the value; use null so conntrack+query-port rule no longer blocks
|
||||
}
|
||||
return fromConfig(status);
|
||||
}
|
||||
|
||||
private static IReadOnlyList<string>? GetEffectiveServerValues(DnsmasqServiceStatus? status, IReadOnlyList<PendingEffectiveConfigChange> pending)
|
||||
|
||||
Reference in New Issue
Block a user