Implement remaining dnsmasq config options and add parser tests

- Add DnsmasqConfKeys for DHCP advanced, DHCPv6/RA, TFTP/PXE, DNSSEC, Other
- Add EffectiveDnsmasqConfig + EffectiveConfigSources for new options
- Wire ConfigSetCache BuildEffectiveConfig/Sources/CreateDefault
- Add EffectiveConfigFieldBuilder sections (TFTP/PXE, DNSSEC), tooltips, registry
- Update EffectiveDnsmasqConfigTests CreateConfig with all new params
- Add one parser test per conf option with documented example (200 tests)
This commit is contained in:
2026-02-11 12:29:15 +10:00
parent dfee96650b
commit 7965fc669b
10 changed files with 1894 additions and 35 deletions
File diff suppressed because it is too large Load Diff
@@ -11,6 +11,7 @@ public class EffectiveDnsmasqConfigTests
new(
NoHosts: false,
AddnHostsPaths: Array.Empty<string>(),
HostsdirPath: null,
ServerLocalValues: Array.Empty<string>(),
RevServerValues: Array.Empty<string>(),
AddressValues: Array.Empty<string>(),
@@ -20,6 +21,15 @@ public class EffectiveDnsmasqConfigTests
DhcpRanges: Array.Empty<string>(),
DhcpHostLines: Array.Empty<string>(),
DhcpOptionLines: Array.Empty<string>(),
DhcpMatchValues: Array.Empty<string>(),
DhcpBootValues: Array.Empty<string>(),
DhcpIgnoreValues: Array.Empty<string>(),
DhcpVendorclassValues: Array.Empty<string>(),
DhcpUserclassValues: Array.Empty<string>(),
RaParamValues: Array.Empty<string>(),
SlaacValues: Array.Empty<string>(),
PxeServiceValues: Array.Empty<string>(),
TrustAnchorValues: Array.Empty<string>(),
ResolvFiles: Array.Empty<string>(),
RebindDomainOkValues: Array.Empty<string>(),
BogusNxdomainValues: Array.Empty<string>(),
@@ -31,6 +41,9 @@ public class EffectiveDnsmasqConfigTests
NoDhcpInterfaceValues: Array.Empty<string>(),
NoDhcpv4InterfaceValues: Array.Empty<string>(),
NoDhcpv6InterfaceValues: Array.Empty<string>(),
DomainValues: Array.Empty<string>(), CnameValues: Array.Empty<string>(), MxHostValues: Array.Empty<string>(), SrvValues: Array.Empty<string>(),
PtrRecordValues: Array.Empty<string>(), TxtRecordValues: Array.Empty<string>(), NaptrRecordValues: Array.Empty<string>(),
HostRecordValues: Array.Empty<string>(), DynamicHostValues: Array.Empty<string>(), InterfaceNameValues: Array.Empty<string>(),
ExpandHosts: false,
BogusPriv: false,
StrictOrder: false,
@@ -52,6 +65,10 @@ public class EffectiveDnsmasqConfigTests
LogDebug: false,
DhcpAuthoritative: false,
LeasefileRo: false,
EnableTftp: false,
TftpSecure: false,
Dnssec: false,
DnssecCheckUnsigned: false,
DhcpLeaseFilePath: null,
CacheSize: null,
Port: null,
@@ -74,7 +91,12 @@ public class EffectiveDnsmasqConfigTests
MaxTtl: null,
MaxCacheTtl: null,
MinCacheTtl: null,
DhcpTtl: null
DhcpTtl: null,
TftpRootPath: null,
PxePrompt: null,
EnableDbus: null,
EnableUbus: null,
FastDnsRetry: null
);
[Fact]
@@ -10,7 +10,10 @@
{
(EffectiveConfigFieldBuilder.SectionHosts, "Hosts"),
(EffectiveConfigFieldBuilder.SectionResolver, "Resolver / DNS"),
(EffectiveConfigFieldBuilder.SectionDnsRecords, "DNS records"),
(EffectiveConfigFieldBuilder.SectionDhcp, "DHCP"),
(EffectiveConfigFieldBuilder.SectionTftpPxe, "TFTP / PXE"),
(EffectiveConfigFieldBuilder.SectionDnssec, "DNSSEC"),
(EffectiveConfigFieldBuilder.SectionCache, "Cache"),
(EffectiveConfigFieldBuilder.SectionProcess, "Process & networking")
};
@@ -14,6 +14,7 @@ public static class DnsmasqConfKeys
// --- Hosts ---
public const string NoHosts = "no-hosts";
public const string AddnHosts = "addn-hosts";
public const string Hostsdir = "hostsdir";
// --- DHCP lease file (last wins) ---
public const string DhcpLeasefile = "dhcp-leasefile";
@@ -34,6 +35,15 @@ public static class DnsmasqConfKeys
public const string DhcpRange = "dhcp-range";
public const string DhcpHost = "dhcp-host";
public const string DhcpOption = "dhcp-option";
public const string DhcpMatch = "dhcp-match";
public const string DhcpBoot = "dhcp-boot";
public const string DhcpIgnore = "dhcp-ignore";
public const string DhcpVendorclass = "dhcp-vendorclass";
public const string DhcpUserclass = "dhcp-userclass";
public const string RaParam = "ra-param";
public const string Slaac = "slaac";
public const string PxeService = "pxe-service";
public const string TrustAnchor = "trust-anchor";
public const string ResolvFile = "resolv-file";
public const string RebindDomainOk = "rebind-domain-ok";
public const string BogusNxdomain = "bogus-nxdomain";
@@ -41,6 +51,17 @@ public static class DnsmasqConfKeys
public const string Alias = "alias";
public const string FilterRr = "filter-rr";
public const string CacheRr = "cache-rr";
// --- DNS records (authoritative / local) ---
public const string Domain = "domain";
public const string Cname = "cname";
public const string MxHost = "mx-host";
public const string Srv = "srv";
public const string PtrRecord = "ptr-record";
public const string TxtRecord = "txt-record";
public const string NaptrRecord = "naptr-record";
public const string HostRecord = "host-record";
public const string DynamicHost = "dynamic-host";
public const string InterfaceName = "interface-name";
// --- Flags (no value) ---
public const string ExpandHosts = "expand-hosts";
@@ -64,6 +85,10 @@ public static class DnsmasqConfKeys
public const string LogDebug = "log-debug";
public const string DhcpAuthoritative = "dhcp-authoritative";
public const string LeasefileRo = "leasefile-ro";
public const string EnableTftp = "enable-tftp";
public const string TftpSecure = "tftp-secure";
public const string Dnssec = "dnssec";
public const string DnssecCheckUnsigned = "dnssec-check-unsigned";
// --- Single-value (last wins) ---
public const string CacheSize = "cache-size";
@@ -88,6 +113,11 @@ public static class DnsmasqConfKeys
public const string MaxCacheTtl = "max-cache-ttl";
public const string MinCacheTtl = "min-cache-ttl";
public const string DhcpTtl = "dhcp-ttl";
public const string TftpRoot = "tftp-root";
public const string PxePrompt = "pxe-prompt";
public const string EnableDbus = "enable-dbus";
public const string EnableUbus = "enable-ubus";
public const string FastDnsRetry = "fast-dns-retry";
/// <summary>Keys collected for effective config "server/local" multi-value (order preserved).</summary>
public static readonly string[] ServerLocalKeys = { Server, Local };
@@ -16,6 +16,7 @@ public static class DnsmasqOptionTooltips
// --- Hosts ---
[DnsmasqConfKeys.NoHosts] = "Do not read /etc/hosts; only use addn-hosts and DHCP/hosts.",
[DnsmasqConfKeys.AddnHosts] = "Additional hosts files (one per line).",
[DnsmasqConfKeys.Hostsdir] = "Directory of hosts files; new/changed files are read automatically.",
// --- Resolver / DNS ---
[DnsmasqConfKeys.ExpandHosts] = "Expand simple names in /etc/hosts with the local domain.",
@@ -44,6 +45,7 @@ public static class DnsmasqOptionTooltips
[DnsmasqConfKeys.FilterA] = "Remove A (IPv4) records from answers.",
[DnsmasqConfKeys.FilterAaaa] = "Remove AAAA (IPv6) records from answers.",
[DnsmasqConfKeys.LocaliseQueries] = "Return interface-specific answers from hosts/DHCP.",
[DnsmasqConfKeys.FastDnsRetry] = "DNS retry parameters: initial delay (ms) and optional continue time (ms).",
[DnsmasqConfKeys.RebindDomainOk] = "Domains exempt from rebind checks. Can repeat.",
[DnsmasqConfKeys.BogusNxdomain] = "Transform replies containing these IPs to NXDOMAIN. Can repeat.",
[DnsmasqConfKeys.IgnoreAddress] = "Ignore A/AAAA replies containing these IPs. Can repeat.",
@@ -55,6 +57,18 @@ public static class DnsmasqOptionTooltips
[DnsmasqConfKeys.NoDhcpv4Interface] = "No DHCPv4 on these interfaces. Can repeat.",
[DnsmasqConfKeys.NoDhcpv6Interface] = "No DHCPv6/RA on these interfaces. Can repeat.",
// --- DNS records ---
[DnsmasqConfKeys.Domain] = "Local domain(s); optional IP. Can repeat (e.g. domain=home,192.168.1.1).",
[DnsmasqConfKeys.Cname] = "CNAME records (alias, target). Can repeat.",
[DnsmasqConfKeys.MxHost] = "MX records (domain, host, priority). Can repeat.",
[DnsmasqConfKeys.Srv] = "SRV records. Can repeat.",
[DnsmasqConfKeys.PtrRecord] = "PTR records for reverse DNS. Can repeat.",
[DnsmasqConfKeys.TxtRecord] = "TXT records. Can repeat.",
[DnsmasqConfKeys.NaptrRecord] = "NAPTR records. Can repeat.",
[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.",
// --- DHCP ---
[DnsmasqConfKeys.DhcpAuthoritative] = "DHCP server is authoritative; required for DHCP to work.",
[DnsmasqConfKeys.LeasefileRo] = "Do not create or truncate the DHCP lease file.",
@@ -64,6 +78,25 @@ public static class DnsmasqOptionTooltips
[DnsmasqConfKeys.DhcpRange] = "DHCP address range(s) and lease time. Can repeat.",
[DnsmasqConfKeys.DhcpHost] = "DHCP host entries (reservations by MAC or client-id). Can repeat.",
[DnsmasqConfKeys.DhcpOption] = "DHCP option lines sent to clients. Can repeat.",
[DnsmasqConfKeys.DhcpMatch] = "Match DHCP clients (e.g. set tag from option). Can repeat.",
[DnsmasqConfKeys.DhcpBoot] = "Boot file and server for PXE. Can repeat.",
[DnsmasqConfKeys.DhcpIgnore] = "Ignore DHCP clients (e.g. by tag). Can repeat.",
[DnsmasqConfKeys.DhcpVendorclass] = "Match by DHCP vendor class. Can repeat.",
[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.",
// --- TFTP / PXE ---
[DnsmasqConfKeys.EnableTftp] = "Enable the built-in TFTP server.",
[DnsmasqConfKeys.TftpSecure] = "Only allow TFTP access from DHCP-assigned clients.",
[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.",
// --- DNSSEC ---
[DnsmasqConfKeys.Dnssec] = "Validate DNSSEC on replies from upstream.",
[DnsmasqConfKeys.DnssecCheckUnsigned] = "Treat unsigned zones as bogus.",
[DnsmasqConfKeys.TrustAnchor] = "DNSSEC trust anchors. Can repeat.",
// --- Cache ---
[DnsmasqConfKeys.CacheSize] = "Maximum number of DNS cache entries (0 to disable).",
@@ -88,6 +121,8 @@ public static class DnsmasqOptionTooltips
[DnsmasqConfKeys.LogAsync] = "Asynchronous logging; optional queue size.",
[DnsmasqConfKeys.BindDynamic] = "Bind per-interface; auto-add new interfaces (Linux).",
[DnsmasqConfKeys.LocalService] = "Restrict to local network or localhost (net|host).",
[DnsmasqConfKeys.EnableDbus] = "Enable DBus interface (optional service name).",
[DnsmasqConfKeys.EnableUbus] = "Enable UBus interface (optional service name).",
}.ToFrozenDictionary();
/// <summary>Returns a short tooltip for the option, or null if none is defined.</summary>
@@ -29,7 +29,10 @@ public static class EffectiveConfigFieldBuilder
public const string SectionHosts = "hosts";
public const string SectionResolver = "resolver";
public const string SectionDnsRecords = "dns-records";
public const string SectionDhcp = "dhcp";
public const string SectionTftpPxe = "tftp-pxe";
public const string SectionDnssec = "dnssec";
public const string SectionCache = "cache";
public const string SectionProcess = "process";
@@ -44,16 +47,19 @@ public static class EffectiveConfigFieldBuilder
list.Add(Single(SectionHosts, DnsmasqConfKeys.NoHosts, status, s => Config(s)?.NoHosts, s => Sources(s)?.NoHosts, null));
list.Add(Multi(SectionHosts, DnsmasqConfKeys.AddnHosts, status,
s => ToValueWithSourceList(s?.AddnHostsPaths, Sources(s)?.AddnHostsPaths)));
list.Add(Single(SectionHosts, DnsmasqConfKeys.Hostsdir, status, s => Config(s)?.HostsdirPath, s => Sources(s)?.HostsdirPath, null));
// --- Resolver / DNS ---
list.Add(Single(SectionResolver, DnsmasqConfKeys.ExpandHosts, status, s => Config(s)?.ExpandHosts, s => Sources(s)?.ExpandHosts, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.BogusPriv, status, s => Config(s)?.BogusPriv, s => Sources(s)?.BogusPriv, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.StrictOrder, status, s => Config(s)?.StrictOrder, s => Sources(s)?.StrictOrder, null));
// --- Resolver / DNS (most-used first: server/local, rev-server, address, resolv-file) ---
list.Add(Multi(SectionResolver, "server / local", status, Items(ec => ec?.ServerLocalValues, src => src?.ServerLocalValues)));
list.Add(Multi(SectionResolver, DnsmasqConfKeys.RevServer, status, Items(ec => ec?.RevServerValues, src => src?.RevServerValues)));
list.Add(Multi(SectionResolver, DnsmasqConfKeys.Address, status, Items(ec => ec?.AddressValues, src => src?.AddressValues)));
list.Add(Multi(SectionResolver, DnsmasqConfKeys.ResolvFile, status, Items(ec => ec?.ResolvFiles, src => src?.ResolvFiles)));
list.Add(Single(SectionResolver, DnsmasqConfKeys.NoResolv, status, s => Config(s)?.NoResolv, s => Sources(s)?.NoResolv, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.DomainNeeded, status, s => Config(s)?.DomainNeeded, s => Sources(s)?.DomainNeeded, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.AllServers, status, s => Config(s)?.AllServers, s => Sources(s)?.AllServers, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.Port, status, s => Config(s)?.Port, s => Sources(s)?.Port, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.LogQueries, status, s => Config(s)?.LogQueries, s => Sources(s)?.LogQueries, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.StrictOrder, status, s => Config(s)?.StrictOrder, s => Sources(s)?.StrictOrder, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.AllServers, status, s => Config(s)?.AllServers, s => Sources(s)?.AllServers, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.AuthTtl, status, s => Config(s)?.AuthTtl, s => Sources(s)?.AuthTtl, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.EdnsPacketMax, status, s => Config(s)?.EdnsPacketMax, s => Sources(s)?.EdnsPacketMax, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.QueryPort, status, s => Config(s)?.QueryPort, s => Sources(s)?.QueryPort, null));
@@ -64,19 +70,30 @@ public static class EffectiveConfigFieldBuilder
list.Add(Single(SectionResolver, DnsmasqConfKeys.StopDnsRebind, status, s => Config(s)?.StopDnsRebind, s => Sources(s)?.StopDnsRebind, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.RebindLocalhostOk, status, s => Config(s)?.RebindLocalhostOk, s => Sources(s)?.RebindLocalhostOk, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.ClearOnReload, status, s => Config(s)?.ClearOnReload, s => Sources(s)?.ClearOnReload, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.Filterwin2k, status, s => Config(s)?.Filterwin2k, s => Sources(s)?.Filterwin2k, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.FilterA, status, s => Config(s)?.FilterA, s => Sources(s)?.FilterA, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.FilterAaaa, status, s => Config(s)?.FilterAaaa, s => Sources(s)?.FilterAaaa, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.LocaliseQueries, status, s => Config(s)?.LocaliseQueries, s => Sources(s)?.LocaliseQueries, null));
list.Add(Multi(SectionResolver, "server / local", status, Items(ec => ec?.ServerLocalValues, src => src?.ServerLocalValues)));
list.Add(Multi(SectionResolver, DnsmasqConfKeys.RevServer, status, Items(ec => ec?.RevServerValues, src => src?.RevServerValues)));
list.Add(Multi(SectionResolver, DnsmasqConfKeys.Address, status, Items(ec => ec?.AddressValues, src => src?.AddressValues)));
list.Add(Multi(SectionResolver, DnsmasqConfKeys.ResolvFile, status, Items(ec => ec?.ResolvFiles, src => src?.ResolvFiles)));
list.Add(Single(SectionResolver, DnsmasqConfKeys.ExpandHosts, status, s => Config(s)?.ExpandHosts, s => Sources(s)?.ExpandHosts, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.BogusPriv, status, s => Config(s)?.BogusPriv, s => Sources(s)?.BogusPriv, null));
list.Add(Multi(SectionResolver, DnsmasqConfKeys.RebindDomainOk, status, Items(ec => ec?.RebindDomainOkValues, src => src?.RebindDomainOkValues)));
list.Add(Multi(SectionResolver, DnsmasqConfKeys.BogusNxdomain, status, Items(ec => ec?.BogusNxdomainValues, src => src?.BogusNxdomainValues)));
list.Add(Multi(SectionResolver, DnsmasqConfKeys.IgnoreAddress, status, Items(ec => ec?.IgnoreAddressValues, src => src?.IgnoreAddressValues)));
list.Add(Multi(SectionResolver, DnsmasqConfKeys.Alias, status, Items(ec => ec?.AliasValues, src => src?.AliasValues)));
list.Add(Multi(SectionResolver, DnsmasqConfKeys.FilterRr, status, Items(ec => ec?.FilterRrValues, src => src?.FilterRrValues)));
list.Add(Single(SectionResolver, DnsmasqConfKeys.Filterwin2k, status, s => Config(s)?.Filterwin2k, s => Sources(s)?.Filterwin2k, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.FilterA, status, s => Config(s)?.FilterA, s => Sources(s)?.FilterA, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.FilterAaaa, status, s => Config(s)?.FilterAaaa, s => Sources(s)?.FilterAaaa, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.LocaliseQueries, status, s => Config(s)?.LocaliseQueries, s => Sources(s)?.LocaliseQueries, null));
list.Add(Single(SectionResolver, DnsmasqConfKeys.FastDnsRetry, status, s => Config(s)?.FastDnsRetry, s => Sources(s)?.FastDnsRetry, null));
// --- DNS records (authoritative / local) ---
list.Add(Multi(SectionDnsRecords, DnsmasqConfKeys.Domain, status, Items(ec => ec?.DomainValues, src => src?.DomainValues)));
list.Add(Multi(SectionDnsRecords, DnsmasqConfKeys.Cname, status, Items(ec => ec?.CnameValues, src => src?.CnameValues)));
list.Add(Multi(SectionDnsRecords, DnsmasqConfKeys.MxHost, status, Items(ec => ec?.MxHostValues, src => src?.MxHostValues)));
list.Add(Multi(SectionDnsRecords, DnsmasqConfKeys.Srv, status, Items(ec => ec?.SrvValues, src => src?.SrvValues)));
list.Add(Multi(SectionDnsRecords, DnsmasqConfKeys.PtrRecord, status, Items(ec => ec?.PtrRecordValues, src => src?.PtrRecordValues)));
list.Add(Multi(SectionDnsRecords, DnsmasqConfKeys.TxtRecord, status, Items(ec => ec?.TxtRecordValues, src => src?.TxtRecordValues)));
list.Add(Multi(SectionDnsRecords, DnsmasqConfKeys.NaptrRecord, status, Items(ec => ec?.NaptrRecordValues, src => src?.NaptrRecordValues)));
list.Add(Multi(SectionDnsRecords, DnsmasqConfKeys.HostRecord, status, Items(ec => ec?.HostRecordValues, src => src?.HostRecordValues)));
list.Add(Multi(SectionDnsRecords, DnsmasqConfKeys.DynamicHost, status, Items(ec => ec?.DynamicHostValues, src => src?.DynamicHostValues)));
list.Add(Multi(SectionDnsRecords, DnsmasqConfKeys.InterfaceName, status, Items(ec => ec?.InterfaceNameValues, src => src?.InterfaceNameValues)));
// --- DHCP ---
list.Add(Single(SectionDhcp, DnsmasqConfKeys.DhcpAuthoritative, status, s => Config(s)?.DhcpAuthoritative, s => Sources(s)?.DhcpAuthoritative, null));
@@ -87,6 +104,25 @@ public static class EffectiveConfigFieldBuilder
list.Add(Multi(SectionDhcp, DnsmasqConfKeys.DhcpRange, status, Items(ec => ec?.DhcpRanges, src => src?.DhcpRanges)));
list.Add(Multi(SectionDhcp, DnsmasqConfKeys.DhcpHost, status, Items(ec => ec?.DhcpHostLines, src => src?.DhcpHostLines)));
list.Add(Multi(SectionDhcp, DnsmasqConfKeys.DhcpOption, status, Items(ec => ec?.DhcpOptionLines, src => src?.DhcpOptionLines)));
list.Add(Multi(SectionDhcp, DnsmasqConfKeys.DhcpMatch, status, Items(ec => ec?.DhcpMatchValues, src => src?.DhcpMatchValues)));
list.Add(Multi(SectionDhcp, DnsmasqConfKeys.DhcpBoot, status, Items(ec => ec?.DhcpBootValues, src => src?.DhcpBootValues)));
list.Add(Multi(SectionDhcp, DnsmasqConfKeys.DhcpIgnore, status, Items(ec => ec?.DhcpIgnoreValues, src => src?.DhcpIgnoreValues)));
list.Add(Multi(SectionDhcp, DnsmasqConfKeys.DhcpVendorclass, status, Items(ec => ec?.DhcpVendorclassValues, src => src?.DhcpVendorclassValues)));
list.Add(Multi(SectionDhcp, DnsmasqConfKeys.DhcpUserclass, status, Items(ec => ec?.DhcpUserclassValues, src => src?.DhcpUserclassValues)));
list.Add(Multi(SectionDhcp, DnsmasqConfKeys.RaParam, status, Items(ec => ec?.RaParamValues, src => src?.RaParamValues)));
list.Add(Multi(SectionDhcp, DnsmasqConfKeys.Slaac, status, Items(ec => ec?.SlaacValues, src => src?.SlaacValues)));
// --- TFTP / PXE ---
list.Add(Single(SectionTftpPxe, DnsmasqConfKeys.EnableTftp, status, s => Config(s)?.EnableTftp, s => Sources(s)?.EnableTftp, null));
list.Add(Single(SectionTftpPxe, DnsmasqConfKeys.TftpSecure, status, s => Config(s)?.TftpSecure, s => Sources(s)?.TftpSecure, null));
list.Add(Single(SectionTftpPxe, DnsmasqConfKeys.TftpRoot, status, s => Config(s)?.TftpRootPath, s => Sources(s)?.TftpRootPath, null));
list.Add(Single(SectionTftpPxe, DnsmasqConfKeys.PxePrompt, status, s => Config(s)?.PxePrompt, s => Sources(s)?.PxePrompt, null));
list.Add(Multi(SectionTftpPxe, DnsmasqConfKeys.PxeService, status, Items(ec => ec?.PxeServiceValues, src => src?.PxeServiceValues)));
// --- DNSSEC ---
list.Add(Single(SectionDnssec, DnsmasqConfKeys.Dnssec, status, s => Config(s)?.Dnssec, s => Sources(s)?.Dnssec, null));
list.Add(Single(SectionDnssec, DnsmasqConfKeys.DnssecCheckUnsigned, status, s => Config(s)?.DnssecCheckUnsigned, s => Sources(s)?.DnssecCheckUnsigned, null));
list.Add(Multi(SectionDnssec, DnsmasqConfKeys.TrustAnchor, status, Items(ec => ec?.TrustAnchorValues, src => src?.TrustAnchorValues)));
// --- Cache ---
list.Add(Multi(SectionCache, DnsmasqConfKeys.CacheRr, status, Items(ec => ec?.CacheRrValues, src => src?.CacheRrValues)));
@@ -116,6 +152,8 @@ public static class EffectiveConfigFieldBuilder
list.Add(Single(SectionProcess, DnsmasqConfKeys.User, status, s => Config(s)?.User, s => Sources(s)?.User, null));
list.Add(Single(SectionProcess, DnsmasqConfKeys.Group, status, s => Config(s)?.Group, s => Sources(s)?.Group, null));
list.Add(Single(SectionProcess, DnsmasqConfKeys.LogFacility, status, s => Config(s)?.LogFacility, s => Sources(s)?.LogFacility, null));
list.Add(Single(SectionProcess, DnsmasqConfKeys.EnableDbus, status, s => Config(s)?.EnableDbus, s => Sources(s)?.EnableDbus, null));
list.Add(Single(SectionProcess, DnsmasqConfKeys.EnableUbus, status, s => Config(s)?.EnableUbus, s => Sources(s)?.EnableUbus, null));
return list;
}
@@ -218,6 +218,8 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
{
var noHosts = DnsmasqConfIncludeParser.GetNoHostsFromConfigFiles(paths, pathToLines);
var addnHosts = DnsmasqConfIncludeParser.GetAddnHostsPathsFromConfigFiles(paths, pathToLines);
var (hostsdirVal, hostsdirDir) = DnsmasqConfIncludeParser.GetLastValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.Hostsdir);
var hostsdirPath = string.IsNullOrWhiteSpace(hostsdirVal) ? null : DnsmasqConfIncludeParser.ResolvePath(hostsdirVal?.Trim(), hostsdirDir);
var serverLocal = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.ServerLocalKeys);
var revServer = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.RevServer);
var addressValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.Address);
@@ -227,6 +229,15 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
var dhcpRanges = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.DhcpRange);
var dhcpHostLines = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.DhcpHost);
var dhcpOptionLines = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.DhcpOption);
var dhcpMatchValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.DhcpMatch);
var dhcpBootValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.DhcpBoot);
var dhcpIgnoreValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.DhcpIgnore);
var dhcpVendorclassValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.DhcpVendorclass);
var dhcpUserclassValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.DhcpUserclass);
var raParamValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.RaParam);
var slaacValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.Slaac);
var pxeServiceValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.PxeService);
var trustAnchorValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.TrustAnchor);
var resolvFiles = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.ResolvFile);
var rebindDomainOk = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.RebindDomainOk);
var bogusNxdomain = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.BogusNxdomain);
@@ -238,6 +249,16 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
var noDhcpInterface = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.NoDhcpInterface);
var noDhcpv4Interface = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.NoDhcpv4Interface);
var noDhcpv6Interface = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.NoDhcpv6Interface);
var domainValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.Domain);
var cnameValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.Cname);
var mxHostValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.MxHost);
var srvValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.Srv);
var ptrRecordValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.PtrRecord);
var txtRecordValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.TxtRecord);
var naptrRecordValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.NaptrRecord);
var hostRecordValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.HostRecord);
var dynamicHostValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.DynamicHost);
var interfaceNameValues = DnsmasqConfIncludeParser.GetMultiValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.InterfaceName);
var expandHosts = DnsmasqConfIncludeParser.GetFlagFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.ExpandHosts);
var bogusPriv = DnsmasqConfIncludeParser.GetFlagFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.BogusPriv);
@@ -260,6 +281,10 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
var logDebug = DnsmasqConfIncludeParser.GetFlagFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.LogDebug);
var dhcpAuthoritative = DnsmasqConfIncludeParser.GetFlagFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.DhcpAuthoritative);
var leasefileRo = DnsmasqConfIncludeParser.GetFlagFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.LeasefileRo);
var enableTftp = DnsmasqConfIncludeParser.GetFlagFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.EnableTftp);
var tftpSecure = DnsmasqConfIncludeParser.GetFlagFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.TftpSecure);
var dnssec = DnsmasqConfIncludeParser.GetFlagFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.Dnssec);
var dnssecCheckUnsigned = DnsmasqConfIncludeParser.GetFlagFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.DnssecCheckUnsigned);
var dhcpLeaseFilePath = DnsmasqConfIncludeParser.GetDhcpLeaseFilePathFromConfigFiles(paths, pathToLines);
@@ -307,16 +332,29 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
var minCacheTtl = TryParseInt(minCacheTtlVal);
var (dhcpTtlVal, _) = DnsmasqConfIncludeParser.GetLastValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.DhcpTtl);
var dhcpTtl = TryParseInt(dhcpTtlVal);
var (tftpRootVal, tftpRootDir) = DnsmasqConfIncludeParser.GetLastValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.TftpRoot);
var tftpRootPath = string.IsNullOrWhiteSpace(tftpRootVal) ? null : DnsmasqConfIncludeParser.ResolvePath(tftpRootVal?.Trim(), tftpRootDir);
var (pxePromptVal, _) = DnsmasqConfIncludeParser.GetLastValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.PxePrompt);
var pxePrompt = string.IsNullOrWhiteSpace(pxePromptVal) ? null : pxePromptVal.Trim();
var (enableDbusVal, _) = DnsmasqConfIncludeParser.GetLastValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.EnableDbus);
var enableDbus = string.IsNullOrWhiteSpace(enableDbusVal) ? null : enableDbusVal.Trim();
var (enableUbusVal, _) = DnsmasqConfIncludeParser.GetLastValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.EnableUbus);
var enableUbus = string.IsNullOrWhiteSpace(enableUbusVal) ? null : enableUbusVal.Trim();
var (fastDnsRetryVal, _) = DnsmasqConfIncludeParser.GetLastValueFromConfigFiles(paths, pathToLines, DnsmasqConfKeys.FastDnsRetry);
var fastDnsRetry = string.IsNullOrWhiteSpace(fastDnsRetryVal) ? null : fastDnsRetryVal.Trim();
return new EffectiveDnsmasqConfig(
noHosts, addnHosts,
serverLocal, revServer, addressValues, interfaces, listenAddresses, exceptInterfaces, dhcpRanges, dhcpHostLines, dhcpOptionLines, resolvFiles,
noHosts, addnHosts, hostsdirPath,
serverLocal, revServer, addressValues, interfaces, listenAddresses, exceptInterfaces, dhcpRanges, dhcpHostLines, dhcpOptionLines,
dhcpMatchValues, dhcpBootValues, dhcpIgnoreValues, dhcpVendorclassValues, dhcpUserclassValues, raParamValues, slaacValues, pxeServiceValues, trustAnchorValues, resolvFiles,
rebindDomainOk, bogusNxdomain, ignoreAddress, alias, filterRr, cacheRr, authServer, noDhcpInterface, noDhcpv4Interface, noDhcpv6Interface,
domainValues, cnameValues, mxHostValues, srvValues, ptrRecordValues, txtRecordValues, naptrRecordValues, hostRecordValues, dynamicHostValues, interfaceNameValues,
expandHosts, bogusPriv, strictOrder, allServers, noResolv, domainNeeded, noPoll, bindInterfaces, bindDynamic, noNegcache,
dnsLoopDetect, stopDnsRebind, rebindLocalhostOk, clearOnReload, filterwin2k, filterA, filterAaaa, localiseQueries, logDebug, dhcpAuthoritative, leasefileRo,
enableTftp, tftpSecure, dnssec, dnssecCheckUnsigned,
dhcpLeaseFilePath, cacheSize, port, localTtl, pidFilePath, user, group, logFacility, logQueries,
authTtl, ednsPacketMax, queryPort, portLimit, minPort, maxPort, logAsync, localService, dhcpLeaseMax,
negTtl, maxTtl, maxCacheTtl, minCacheTtl, dhcpTtl
negTtl, maxTtl, maxCacheTtl, minCacheTtl, dhcpTtl, tftpRootPath, pxePrompt, enableDbus, enableUbus, fastDnsRetry
);
}
@@ -324,6 +362,7 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
{
var (_, noHostsSource) = DnsmasqConfIncludeParser.GetFlagFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.NoHosts, managedFilePath);
var addnHostsWithSource = DnsmasqConfIncludeParser.GetAddnHostsPathsFromConfigFilesWithSource(paths, pathToLines, managedFilePath);
var (_, hostsdirPathSource) = DnsmasqConfIncludeParser.GetLastValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.Hostsdir, managedFilePath);
var serverLocalWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.ServerLocalKeys, managedFilePath);
var revServerWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.RevServer, managedFilePath);
var addressWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.Address, managedFilePath);
@@ -333,6 +372,15 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
var dhcpRangesWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpRange, managedFilePath);
var dhcpHostLinesWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpHost, managedFilePath);
var dhcpOptionLinesWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpOption, managedFilePath);
var dhcpMatchWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpMatch, managedFilePath);
var dhcpBootWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpBoot, managedFilePath);
var dhcpIgnoreWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpIgnore, managedFilePath);
var dhcpVendorclassWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpVendorclass, managedFilePath);
var dhcpUserclassWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpUserclass, managedFilePath);
var raParamWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.RaParam, managedFilePath);
var slaacWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.Slaac, managedFilePath);
var pxeServiceWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.PxeService, managedFilePath);
var trustAnchorWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.TrustAnchor, managedFilePath);
var resolvFilesWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.ResolvFile, managedFilePath);
var rebindDomainOkWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.RebindDomainOk, managedFilePath);
var bogusNxdomainWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.BogusNxdomain, managedFilePath);
@@ -344,6 +392,16 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
var noDhcpInterfaceWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.NoDhcpInterface, managedFilePath);
var noDhcpv4InterfaceWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.NoDhcpv4Interface, managedFilePath);
var noDhcpv6InterfaceWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.NoDhcpv6Interface, managedFilePath);
var domainWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.Domain, managedFilePath);
var cnameWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.Cname, managedFilePath);
var mxHostWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.MxHost, managedFilePath);
var srvWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.Srv, managedFilePath);
var ptrRecordWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.PtrRecord, managedFilePath);
var txtRecordWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.TxtRecord, managedFilePath);
var naptrRecordWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.NaptrRecord, managedFilePath);
var hostRecordWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.HostRecord, managedFilePath);
var dynamicHostWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.DynamicHost, managedFilePath);
var interfaceNameWithSource = DnsmasqConfIncludeParser.GetMultiValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.InterfaceName, managedFilePath);
var (_, expandHostsSource) = DnsmasqConfIncludeParser.GetFlagFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.ExpandHosts, managedFilePath);
var (_, bogusPrivSource) = DnsmasqConfIncludeParser.GetFlagFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.BogusPriv, managedFilePath);
@@ -366,6 +424,10 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
var (_, logDebugSource) = DnsmasqConfIncludeParser.GetFlagFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.LogDebug, managedFilePath);
var (_, dhcpAuthoritativeSource) = DnsmasqConfIncludeParser.GetFlagFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpAuthoritative, managedFilePath);
var (_, leasefileRoSource) = DnsmasqConfIncludeParser.GetFlagFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.LeasefileRo, managedFilePath);
var (_, enableTftpSource) = DnsmasqConfIncludeParser.GetFlagFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.EnableTftp, managedFilePath);
var (_, tftpSecureSource) = DnsmasqConfIncludeParser.GetFlagFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.TftpSecure, managedFilePath);
var (_, dnssecSource) = DnsmasqConfIncludeParser.GetFlagFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.Dnssec, managedFilePath);
var (_, dnssecCheckUnsignedSource) = DnsmasqConfIncludeParser.GetFlagFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.DnssecCheckUnsigned, managedFilePath);
var (_, dhcpLeaseFilePathSource) = DnsmasqConfIncludeParser.GetDhcpLeaseFilePathFromConfigFilesWithSource(paths, pathToLines, managedFilePath);
var (_, cacheSizeSource) = DnsmasqConfIncludeParser.GetLastValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.CacheSize, managedFilePath);
@@ -390,9 +452,14 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
var (_, maxCacheTtlSource) = DnsmasqConfIncludeParser.GetLastValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.MaxCacheTtl, managedFilePath);
var (_, minCacheTtlSource) = DnsmasqConfIncludeParser.GetLastValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.MinCacheTtl, managedFilePath);
var (_, dhcpTtlSource) = DnsmasqConfIncludeParser.GetLastValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.DhcpTtl, managedFilePath);
var (_, tftpRootPathSource) = DnsmasqConfIncludeParser.GetLastValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.TftpRoot, managedFilePath);
var (_, pxePromptSource) = DnsmasqConfIncludeParser.GetLastValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.PxePrompt, managedFilePath);
var (_, enableDbusSource) = DnsmasqConfIncludeParser.GetLastValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.EnableDbus, managedFilePath);
var (_, enableUbusSource) = DnsmasqConfIncludeParser.GetLastValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.EnableUbus, managedFilePath);
var (_, fastDnsRetrySource) = DnsmasqConfIncludeParser.GetLastValueFromConfigFilesWithSource(paths, pathToLines, DnsmasqConfKeys.FastDnsRetry, managedFilePath);
return new EffectiveConfigSources(
noHostsSource, addnHostsWithSource.Select(t => new PathWithSource(t.Path, t.Source)).ToList(),
noHostsSource, addnHostsWithSource.Select(t => new PathWithSource(t.Path, t.Source)).ToList(), hostsdirPathSource,
serverLocalWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
revServerWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
addressWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
@@ -402,6 +469,15 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
dhcpRangesWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
dhcpHostLinesWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
dhcpOptionLinesWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
dhcpMatchWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
dhcpBootWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
dhcpIgnoreWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
dhcpVendorclassWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
dhcpUserclassWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
raParamWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
slaacWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
pxeServiceWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
trustAnchorWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
resolvFilesWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
rebindDomainOkWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
bogusNxdomainWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
@@ -413,12 +489,69 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
noDhcpInterfaceWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
noDhcpv4InterfaceWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
noDhcpv6InterfaceWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
expandHostsSource, bogusPrivSource, strictOrderSource, allServersSource, noResolvSource, domainNeededSource, noPollSource,
bindInterfacesSource, bindDynamicSource, noNegcacheSource, dnsLoopDetectSource, stopDnsRebindSource, rebindLocalhostOkSource, clearOnReloadSource,
filterwin2kSource, filterASource, filterAaaaSource, localiseQueriesSource, logDebugSource, dhcpAuthoritativeSource, leasefileRoSource,
dhcpLeaseFilePathSource, cacheSizeSource, portSource, localTtlSource, pidFilePathSource, userSource, groupSource,
logFacilitySource, logQueriesSource, authTtlSource, ednsPacketMaxSource, queryPortSource, portLimitSource, minPortSource, maxPortSource, logAsyncSource, localServiceSource,
dhcpLeaseMaxSource, negTtlSource, maxTtlSource, maxCacheTtlSource, minCacheTtlSource, dhcpTtlSource
domainWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
cnameWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
mxHostWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
srvWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
ptrRecordWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
txtRecordWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
naptrRecordWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
hostRecordWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
dynamicHostWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
interfaceNameWithSource.Select(t => new ValueWithSource(t.Value, t.Source)).ToList(),
expandHostsSource,
bogusPrivSource,
strictOrderSource,
allServersSource,
noResolvSource,
domainNeededSource,
noPollSource,
bindInterfacesSource,
bindDynamicSource,
noNegcacheSource,
dnsLoopDetectSource,
stopDnsRebindSource,
rebindLocalhostOkSource,
clearOnReloadSource,
filterwin2kSource,
filterASource,
filterAaaaSource,
localiseQueriesSource,
logDebugSource,
dhcpAuthoritativeSource,
leasefileRoSource,
enableTftpSource,
tftpSecureSource,
dnssecSource,
dnssecCheckUnsignedSource,
dhcpLeaseFilePathSource,
cacheSizeSource,
portSource,
localTtlSource,
pidFilePathSource,
userSource,
groupSource,
logFacilitySource,
logQueriesSource,
authTtlSource,
ednsPacketMaxSource,
queryPortSource,
portLimitSource,
minPortSource,
maxPortSource,
logAsyncSource,
localServiceSource,
dhcpLeaseMaxSource,
negTtlSource,
maxTtlSource,
maxCacheTtlSource,
minCacheTtlSource,
dhcpTtlSource,
tftpRootPathSource,
pxePromptSource,
enableDbusSource,
enableUbusSource,
fastDnsRetrySource
);
}
@@ -456,38 +589,56 @@ public sealed class ConfigSetCache : IConfigSetCache, IDisposable
private static EffectiveDnsmasqConfig CreateDefaultEffectiveConfig() =>
new(
NoHosts: false, AddnHostsPaths: Array.Empty<string>(),
NoHosts: false, AddnHostsPaths: Array.Empty<string>(), HostsdirPath: null,
ServerLocalValues: Array.Empty<string>(), RevServerValues: Array.Empty<string>(), AddressValues: Array.Empty<string>(), Interfaces: Array.Empty<string>(),
ListenAddresses: Array.Empty<string>(), ExceptInterfaces: Array.Empty<string>(), DhcpRanges: Array.Empty<string>(),
DhcpHostLines: Array.Empty<string>(), DhcpOptionLines: Array.Empty<string>(), ResolvFiles: Array.Empty<string>(),
RebindDomainOkValues: Array.Empty<string>(), BogusNxdomainValues: Array.Empty<string>(), IgnoreAddressValues: Array.Empty<string>(),
DhcpHostLines: Array.Empty<string>(), DhcpOptionLines: Array.Empty<string>(),
DhcpMatchValues: Array.Empty<string>(), DhcpBootValues: Array.Empty<string>(), DhcpIgnoreValues: Array.Empty<string>(),
DhcpVendorclassValues: Array.Empty<string>(), DhcpUserclassValues: Array.Empty<string>(),
RaParamValues: Array.Empty<string>(), SlaacValues: Array.Empty<string>(), PxeServiceValues: Array.Empty<string>(), TrustAnchorValues: Array.Empty<string>(),
ResolvFiles: Array.Empty<string>(), RebindDomainOkValues: Array.Empty<string>(), BogusNxdomainValues: Array.Empty<string>(), IgnoreAddressValues: Array.Empty<string>(),
AliasValues: Array.Empty<string>(), FilterRrValues: Array.Empty<string>(), CacheRrValues: Array.Empty<string>(),
AuthServerValues: Array.Empty<string>(), NoDhcpInterfaceValues: Array.Empty<string>(), NoDhcpv4InterfaceValues: Array.Empty<string>(), NoDhcpv6InterfaceValues: Array.Empty<string>(),
AuthServerValues: Array.Empty<string>(), NoDhcpInterfaceValues: Array.Empty<string>(), NoDhcpv4InterfaceValues: Array.Empty<string>(), NoDhcpv6InterfaceValues: Array.Empty<string>(),
DomainValues: Array.Empty<string>(), CnameValues: Array.Empty<string>(), MxHostValues: Array.Empty<string>(), SrvValues: Array.Empty<string>(),
PtrRecordValues: Array.Empty<string>(), TxtRecordValues: Array.Empty<string>(), NaptrRecordValues: Array.Empty<string>(),
HostRecordValues: Array.Empty<string>(), DynamicHostValues: Array.Empty<string>(), InterfaceNameValues: 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, Dnssec: false, DnssecCheckUnsigned: 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
DhcpLeaseMax: null, NegTtl: null, MaxTtl: null, MaxCacheTtl: null, MinCacheTtl: null, DhcpTtl: null,
TftpRootPath: null, PxePrompt: null, EnableDbus: null, EnableUbus: null, FastDnsRetry: null
);
private static EffectiveConfigSources CreateDefaultEffectiveConfigSources() =>
new(
NoHosts: null, AddnHostsPaths: Array.Empty<PathWithSource>(),
NoHosts: null, AddnHostsPaths: Array.Empty<PathWithSource>(), HostsdirPath: null,
ServerLocalValues: Array.Empty<ValueWithSource>(), RevServerValues: Array.Empty<ValueWithSource>(), AddressValues: Array.Empty<ValueWithSource>(),
Interfaces: Array.Empty<ValueWithSource>(), ListenAddresses: Array.Empty<ValueWithSource>(),
ExceptInterfaces: Array.Empty<ValueWithSource>(), DhcpRanges: Array.Empty<ValueWithSource>(),
DhcpHostLines: Array.Empty<ValueWithSource>(), DhcpOptionLines: Array.Empty<ValueWithSource>(),
DhcpHostLines: Array.Empty<ValueWithSource>(),
DhcpOptionLines: Array.Empty<ValueWithSource>(),
DhcpMatchValues: Array.Empty<ValueWithSource>(), DhcpBootValues: Array.Empty<ValueWithSource>(), DhcpIgnoreValues: Array.Empty<ValueWithSource>(),
DhcpVendorclassValues: Array.Empty<ValueWithSource>(), DhcpUserclassValues: Array.Empty<ValueWithSource>(),
RaParamValues: Array.Empty<ValueWithSource>(), SlaacValues: Array.Empty<ValueWithSource>(), PxeServiceValues: Array.Empty<ValueWithSource>(), TrustAnchorValues: Array.Empty<ValueWithSource>(),
ResolvFiles: Array.Empty<ValueWithSource>(),
RebindDomainOkValues: Array.Empty<ValueWithSource>(), BogusNxdomainValues: Array.Empty<ValueWithSource>(), IgnoreAddressValues: Array.Empty<ValueWithSource>(),
AliasValues: Array.Empty<ValueWithSource>(), FilterRrValues: Array.Empty<ValueWithSource>(), CacheRrValues: Array.Empty<ValueWithSource>(),
AuthServerValues: Array.Empty<ValueWithSource>(), NoDhcpInterfaceValues: Array.Empty<ValueWithSource>(), NoDhcpv4InterfaceValues: Array.Empty<ValueWithSource>(), NoDhcpv6InterfaceValues: Array.Empty<ValueWithSource>(),
AuthServerValues: Array.Empty<ValueWithSource>(), NoDhcpInterfaceValues: Array.Empty<ValueWithSource>(), NoDhcpv4InterfaceValues: Array.Empty<ValueWithSource>(),
NoDhcpv6InterfaceValues: Array.Empty<ValueWithSource>(),
DomainValues: Array.Empty<ValueWithSource>(), CnameValues: Array.Empty<ValueWithSource>(), MxHostValues: Array.Empty<ValueWithSource>(), SrvValues: Array.Empty<ValueWithSource>(),
PtrRecordValues: Array.Empty<ValueWithSource>(), TxtRecordValues: Array.Empty<ValueWithSource>(), NaptrRecordValues: Array.Empty<ValueWithSource>(),
HostRecordValues: Array.Empty<ValueWithSource>(), DynamicHostValues: Array.Empty<ValueWithSource>(), InterfaceNameValues: 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, Dnssec: null, DnssecCheckUnsigned: 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
DhcpLeaseMax: null, NegTtl: null, MaxTtl: null, MaxCacheTtl: null, MinCacheTtl: null, DhcpTtl: null,
TftpRootPath: null, PxePrompt: null, EnableDbus: null, EnableUbus: null, FastDnsRetry: null
);
private static int? TryParseInt(string? value)
@@ -43,6 +43,10 @@ public class EffectiveConfigRenderFragmentRegistry : IEffectiveConfigRenderFragm
RegisterFlag(EffectiveConfigFieldBuilder.SectionResolver, DnsmasqConfKeys.LocaliseQueries);
RegisterFlag(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.DhcpAuthoritative);
RegisterFlag(EffectiveConfigFieldBuilder.SectionDhcp, DnsmasqConfKeys.LeasefileRo);
RegisterFlag(EffectiveConfigFieldBuilder.SectionTftpPxe, DnsmasqConfKeys.EnableTftp);
RegisterFlag(EffectiveConfigFieldBuilder.SectionTftpPxe, DnsmasqConfKeys.TftpSecure);
RegisterFlag(EffectiveConfigFieldBuilder.SectionDnssec, DnsmasqConfKeys.Dnssec);
RegisterFlag(EffectiveConfigFieldBuilder.SectionDnssec, DnsmasqConfKeys.DnssecCheckUnsigned);
}
private void RegisterFlag(string sectionId, string optionName)
@@ -13,6 +13,7 @@ public record EffectiveConfigSources(
// --- Hosts ---
ConfigValueSource? NoHosts,
IReadOnlyList<PathWithSource> AddnHostsPaths,
ConfigValueSource? HostsdirPath,
// --- Multi-value (ARG_DUP): source per value ---
IReadOnlyList<ValueWithSource> ServerLocalValues,
@@ -24,6 +25,15 @@ public record EffectiveConfigSources(
IReadOnlyList<ValueWithSource> DhcpRanges,
IReadOnlyList<ValueWithSource> DhcpHostLines,
IReadOnlyList<ValueWithSource> DhcpOptionLines,
IReadOnlyList<ValueWithSource> DhcpMatchValues,
IReadOnlyList<ValueWithSource> DhcpBootValues,
IReadOnlyList<ValueWithSource> DhcpIgnoreValues,
IReadOnlyList<ValueWithSource> DhcpVendorclassValues,
IReadOnlyList<ValueWithSource> DhcpUserclassValues,
IReadOnlyList<ValueWithSource> RaParamValues,
IReadOnlyList<ValueWithSource> SlaacValues,
IReadOnlyList<ValueWithSource> PxeServiceValues,
IReadOnlyList<ValueWithSource> TrustAnchorValues,
IReadOnlyList<ValueWithSource> ResolvFiles,
IReadOnlyList<ValueWithSource> RebindDomainOkValues,
IReadOnlyList<ValueWithSource> BogusNxdomainValues,
@@ -35,6 +45,16 @@ public record EffectiveConfigSources(
IReadOnlyList<ValueWithSource> NoDhcpInterfaceValues,
IReadOnlyList<ValueWithSource> NoDhcpv4InterfaceValues,
IReadOnlyList<ValueWithSource> NoDhcpv6InterfaceValues,
IReadOnlyList<ValueWithSource> DomainValues,
IReadOnlyList<ValueWithSource> CnameValues,
IReadOnlyList<ValueWithSource> MxHostValues,
IReadOnlyList<ValueWithSource> SrvValues,
IReadOnlyList<ValueWithSource> PtrRecordValues,
IReadOnlyList<ValueWithSource> TxtRecordValues,
IReadOnlyList<ValueWithSource> NaptrRecordValues,
IReadOnlyList<ValueWithSource> HostRecordValues,
IReadOnlyList<ValueWithSource> DynamicHostValues,
IReadOnlyList<ValueWithSource> InterfaceNameValues,
// --- Flags (set if any occurrence; source = first file that set it, so we know if readonly) ---
ConfigValueSource? ExpandHosts,
@@ -58,6 +78,10 @@ public record EffectiveConfigSources(
ConfigValueSource? LogDebug,
ConfigValueSource? DhcpAuthoritative,
ConfigValueSource? LeasefileRo,
ConfigValueSource? EnableTftp,
ConfigValueSource? TftpSecure,
ConfigValueSource? Dnssec,
ConfigValueSource? DnssecCheckUnsigned,
// --- Single-value (last occurrence wins; source = file that set the last value) ---
ConfigValueSource? DhcpLeaseFilePath,
@@ -82,5 +106,10 @@ public record EffectiveConfigSources(
ConfigValueSource? MaxTtl,
ConfigValueSource? MaxCacheTtl,
ConfigValueSource? MinCacheTtl,
ConfigValueSource? DhcpTtl
ConfigValueSource? DhcpTtl,
ConfigValueSource? TftpRootPath,
ConfigValueSource? PxePrompt,
ConfigValueSource? EnableDbus,
ConfigValueSource? EnableUbus,
ConfigValueSource? FastDnsRetry
);
@@ -17,6 +17,7 @@ public record EffectiveDnsmasqConfig(
// --- Hosts (already used by Hosts UI) ---
bool NoHosts,
IReadOnlyList<string> AddnHostsPaths,
string? HostsdirPath,
// --- Multi-value (ARG_DUP): all occurrences in order ---
IReadOnlyList<string> ServerLocalValues,
@@ -28,6 +29,15 @@ public record EffectiveDnsmasqConfig(
IReadOnlyList<string> DhcpRanges,
IReadOnlyList<string> DhcpHostLines,
IReadOnlyList<string> DhcpOptionLines,
IReadOnlyList<string> DhcpMatchValues,
IReadOnlyList<string> DhcpBootValues,
IReadOnlyList<string> DhcpIgnoreValues,
IReadOnlyList<string> DhcpVendorclassValues,
IReadOnlyList<string> DhcpUserclassValues,
IReadOnlyList<string> RaParamValues,
IReadOnlyList<string> SlaacValues,
IReadOnlyList<string> PxeServiceValues,
IReadOnlyList<string> TrustAnchorValues,
IReadOnlyList<string> ResolvFiles,
IReadOnlyList<string> RebindDomainOkValues,
IReadOnlyList<string> BogusNxdomainValues,
@@ -39,6 +49,16 @@ public record EffectiveDnsmasqConfig(
IReadOnlyList<string> NoDhcpInterfaceValues,
IReadOnlyList<string> NoDhcpv4InterfaceValues,
IReadOnlyList<string> NoDhcpv6InterfaceValues,
IReadOnlyList<string> DomainValues,
IReadOnlyList<string> CnameValues,
IReadOnlyList<string> MxHostValues,
IReadOnlyList<string> SrvValues,
IReadOnlyList<string> PtrRecordValues,
IReadOnlyList<string> TxtRecordValues,
IReadOnlyList<string> NaptrRecordValues,
IReadOnlyList<string> HostRecordValues,
IReadOnlyList<string> DynamicHostValues,
IReadOnlyList<string> InterfaceNameValues,
// --- Boolean flags (set if any file contains the option) ---
bool ExpandHosts,
@@ -62,6 +82,10 @@ public record EffectiveDnsmasqConfig(
bool LogDebug,
bool DhcpAuthoritative,
bool LeasefileRo,
bool EnableTftp,
bool TftpSecure,
bool Dnssec,
bool DnssecCheckUnsigned,
// --- Single-value options (last occurrence wins; null = not set, dnsmasq default) ---
string? DhcpLeaseFilePath,
@@ -86,7 +110,12 @@ public record EffectiveDnsmasqConfig(
int? MaxTtl,
int? MaxCacheTtl,
int? MinCacheTtl,
int? DhcpTtl
int? DhcpTtl,
string? TftpRootPath,
string? PxePrompt,
string? EnableDbus,
string? EnableUbus,
string? FastDnsRetry
)
{
/// <summary>