From 715289902ae34ff78ae3fec775412a34dabc4458 Mon Sep 17 00:00:00 2001 From: Shreyas Zare Date: Sat, 10 Jul 2021 13:20:52 +0530 Subject: [PATCH] AuthZoneInfo: implemented zone history property for IXFR support. Added TriggerResync() method. Code refactoring done. --- DnsServerCore/Dns/Zones/AuthZoneInfo.cs | 105 ++++++++++++++++++++---- 1 file changed, 87 insertions(+), 18 deletions(-) diff --git a/DnsServerCore/Dns/Zones/AuthZoneInfo.cs b/DnsServerCore/Dns/Zones/AuthZoneInfo.cs index 0e95d253..e7623226 100644 --- a/DnsServerCore/Dns/Zones/AuthZoneInfo.cs +++ b/DnsServerCore/Dns/Zones/AuthZoneInfo.cs @@ -17,6 +17,7 @@ along with this program. If not, see . */ +using DnsServerCore.Dns.ResourceRecords; using System; using System.Collections.Generic; using System.IO; @@ -51,6 +52,7 @@ namespace DnsServerCore.Dns.Zones readonly AuthZoneNotify _notify; readonly IReadOnlyCollection _notifyNameServers; readonly DateTime _expiry; + readonly IReadOnlyList _zoneHistory; //for IXFR support #endregion @@ -83,6 +85,7 @@ namespace DnsServerCore.Dns.Zones { case 1: case 2: + case 3: _name = bR.ReadShortString(); _type = (AuthZoneType)bR.ReadByte(); _disabled = bR.ReadBoolean(); @@ -137,12 +140,29 @@ namespace DnsServerCore.Dns.Zones switch (_type) { + case AuthZoneType.Primary: + if (version >= 3) + { + int count = bR.ReadInt32(); + DnsResourceRecord[] zoneHistory = new DnsResourceRecord[count]; + + for (int i = 0; i < count; i++) + { + zoneHistory[i] = new DnsResourceRecord(bR.BaseStream); + zoneHistory[i].Tag = new DnsResourceRecordInfo(bR, zoneHistory[i].Type == DnsResourceRecordType.SOA); + } + + _zoneHistory = zoneHistory; + } + + break; + case AuthZoneType.Secondary: - _expiry = bR.ReadDate(); + _expiry = bR.ReadDateTime(); break; case AuthZoneType.Stub: - _expiry = bR.ReadDate(); + _expiry = bR.ReadDateTime(); break; } @@ -153,38 +173,42 @@ namespace DnsServerCore.Dns.Zones } } - internal AuthZoneInfo(AuthZone zone) + internal AuthZoneInfo(AuthZone zone, bool loadHistory = false) { _zone = zone; _name = _zone.Name; - if (_zone is PrimaryZone) + if (_zone is PrimaryZone primaryZone) + { _type = AuthZoneType.Primary; - else if (_zone is SecondaryZone) + + if (loadHistory) + _zoneHistory = primaryZone.GetHistory(); + } + else if (_zone is SecondaryZone secondaryZone) + { _type = AuthZoneType.Secondary; - else if (_zone is StubZone) + _expiry = secondaryZone.Expiry; + } + else if (_zone is StubZone stubZone) + { _type = AuthZoneType.Stub; + _expiry = stubZone.Expiry; + } else if (_zone is ForwarderZone) + { _type = AuthZoneType.Forwarder; + } else + { _type = AuthZoneType.Unknown; + } _disabled = _zone.Disabled; _zoneTransfer = zone.ZoneTransfer; _zoneTransferNameServers = zone.ZoneTransferNameServers; _notify = zone.Notify; _notifyNameServers = zone.NotifyNameServers; - - switch (_type) - { - case AuthZoneType.Secondary: - _expiry = (_zone as SecondaryZone).Expiry; - break; - - case AuthZoneType.Stub: - _expiry = (_zone as StubZone).Expiry; - break; - } } #endregion @@ -239,6 +263,26 @@ namespace DnsServerCore.Dns.Zones } } + public void TriggerResync() + { + if (_zone == null) + throw new InvalidOperationException(); + + switch (_type) + { + case AuthZoneType.Secondary: + (_zone as SecondaryZone).TriggerResync(); + break; + + case AuthZoneType.Stub: + (_zone as StubZone).TriggerResync(); + break; + + default: + throw new InvalidOperationException(); + } + } + public Task> GetPrimaryNameServerAddressesAsync(DnsServer dnsServer) { if (_zone == null) @@ -260,7 +304,7 @@ namespace DnsServerCore.Dns.Zones if (_zone == null) throw new InvalidOperationException(); - bW.Write((byte)2); //version + bW.Write((byte)3); //version bW.WriteShortString(_name); bW.Write((byte)_type); @@ -293,6 +337,28 @@ namespace DnsServerCore.Dns.Zones switch (_type) { + case AuthZoneType.Primary: + if (_zoneHistory is null) + { + bW.Write(0); + } + else + { + bW.Write(_zoneHistory.Count); + + foreach (DnsResourceRecord record in _zoneHistory) + { + record.WriteTo(bW.BaseStream); + + if (record.Tag is not DnsResourceRecordInfo rrInfo) + rrInfo = new DnsResourceRecordInfo(); //default info + + rrInfo.WriteTo(bW); + } + } + + break; + case AuthZoneType.Secondary: bW.Write(_expiry); break; @@ -417,6 +483,9 @@ namespace DnsServerCore.Dns.Zones } } + public IReadOnlyList ZoneHistory + { get { return _zoneHistory; } } + #endregion } }