AuthRecordInfo: refactored implementation to add specialized record info classes.

This commit is contained in:
Shreyas Zare
2024-06-01 17:56:10 +05:30
parent 4aaee382d8
commit cc9728764e
7 changed files with 843 additions and 232 deletions

View File

@@ -1,6 +1,6 @@
/*
Technitium DNS Server
Copyright (C) 2023 Shreyas Zare (shreyas@technitium.com)
Copyright (C) 2024 Shreyas Zare (shreyas@technitium.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,7 +18,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using TechnitiumLibrary.IO;
@@ -27,37 +26,60 @@ using TechnitiumLibrary.Net.Dns.ResourceRecords;
namespace DnsServerCore.Dns.ResourceRecords
{
class AuthRecordInfo
abstract class AuthRecordInfo
{
#region variables
#region constructor
public static readonly AuthRecordInfo Default = new AuthRecordInfo();
protected AuthRecordInfo()
{ }
bool _disabled;
IReadOnlyList<DnsResourceRecord> _glueRecords;
string _comments;
DateTime _deletedOn;
IReadOnlyList<NameServerAddress> _primaryNameServers;
DnsTransportProtocol _zoneTransferProtocol;
string _tsigKeyName = string.Empty;
bool _useSoaSerialDateScheme;
DateTime _lastUsedOn; //not serialized
protected AuthRecordInfo(BinaryReader bR)
{
byte version = bR.ReadByte();
if (version >= 9)
ReadRecordInfoFrom(bR);
else
ReadOldFormatFrom(bR, version, this is SOARecordInfo);
}
#endregion
#region constructor
#region static
public AuthRecordInfo()
{ }
public AuthRecordInfo(BinaryReader bR, bool isSoa)
public static GenericRecordInfo ReadGenericRecordInfoFrom(BinaryReader bR, DnsResourceRecordType type)
{
switch (type)
{
case DnsResourceRecordType.NS:
return new NSRecordInfo(bR);
case DnsResourceRecordType.SOA:
return new SOARecordInfo(bR);
case DnsResourceRecordType.SVCB:
case DnsResourceRecordType.HTTPS:
return new SVCBRecordInfo(bR);
default:
return new GenericRecordInfo(bR);
}
}
#endregion
#region private
private void ReadOldFormatFrom(BinaryReader bR, byte version, bool isSoa)
{
byte version = bR.ReadByte();
switch (version)
{
case 1:
_disabled = bR.ReadBoolean();
{
bool disabled = bR.ReadBoolean();
if (this is GenericRecordInfo info)
info.Disabled = disabled;
}
break;
case 2:
@@ -67,94 +89,134 @@ namespace DnsServerCore.Dns.ResourceRecords
case 6:
case 7:
case 8:
_disabled = bR.ReadBoolean();
if ((version < 5) && isSoa)
{
//read old glue records as NameServerAddress in case of SOA record
int count = bR.ReadByte();
if (count > 0)
{
NameServerAddress[] primaryNameServers = new NameServerAddress[count];
bool disabled = bR.ReadBoolean();
for (int i = 0; i < primaryNameServers.Length; i++)
if (this is GenericRecordInfo info)
info.Disabled = disabled;
}
if ((version < 5) && isSoa)
{
//read old glue records as NameServerAddress in case of SOA record
int count = bR.ReadByte();
if (count > 0)
{
DnsResourceRecord glueRecord = new DnsResourceRecord(bR.BaseStream);
NameServerAddress[] primaryNameServers = new NameServerAddress[count];
IPAddress address;
switch (glueRecord.Type)
for (int i = 0; i < primaryNameServers.Length; i++)
{
case DnsResourceRecordType.A:
address = (glueRecord.RDATA as DnsARecordData).Address;
break;
DnsResourceRecord glueRecord = new DnsResourceRecord(bR.BaseStream);
case DnsResourceRecordType.AAAA:
address = (glueRecord.RDATA as DnsAAAARecordData).Address;
break;
IPAddress address;
default:
continue;
switch (glueRecord.Type)
{
case DnsResourceRecordType.A:
address = (glueRecord.RDATA as DnsARecordData).Address;
break;
case DnsResourceRecordType.AAAA:
address = (glueRecord.RDATA as DnsAAAARecordData).Address;
break;
default:
continue;
}
primaryNameServers[i] = new NameServerAddress(address);
}
primaryNameServers[i] = new NameServerAddress(address);
(this as SOARecordInfo).PrimaryNameServers = primaryNameServers;
}
_primaryNameServers = primaryNameServers;
}
}
else
{
int count = bR.ReadByte();
if (count > 0)
else
{
DnsResourceRecord[] glueRecords = new DnsResourceRecord[count];
int count = bR.ReadByte();
if (count > 0)
{
DnsResourceRecord[] glueRecords = new DnsResourceRecord[count];
for (int i = 0; i < glueRecords.Length; i++)
glueRecords[i] = new DnsResourceRecord(bR.BaseStream);
for (int i = 0; i < glueRecords.Length; i++)
glueRecords[i] = new DnsResourceRecord(bR.BaseStream);
_glueRecords = glueRecords;
if (this is NSRecordInfo info)
info.GlueRecords = glueRecords;
}
}
}
if (version >= 3)
_comments = bR.ReadShortString();
if (version >= 4)
_deletedOn = bR.ReadDateTime();
if (version >= 5)
{
int count = bR.ReadByte();
if (count > 0)
if (version >= 3)
{
NameServerAddress[] primaryNameServers = new NameServerAddress[count];
string comments = bR.ReadShortString();
for (int i = 0; i < primaryNameServers.Length; i++)
primaryNameServers[i] = new NameServerAddress(bR);
if (this is GenericRecordInfo info)
info.Comments = comments;
}
_primaryNameServers = primaryNameServers;
if (version >= 4)
{
DateTime deletedOn = bR.ReadDateTime();
if (this is HistoryRecordInfo info)
info.DeletedOn = deletedOn;
}
if (version >= 5)
{
int count = bR.ReadByte();
if (count > 0)
{
NameServerAddress[] primaryNameServers = new NameServerAddress[count];
for (int i = 0; i < primaryNameServers.Length; i++)
primaryNameServers[i] = new NameServerAddress(bR);
if (this is SOARecordInfo info)
info.PrimaryNameServers = primaryNameServers;
}
}
if (version >= 7)
{
DnsTransportProtocol zoneTransferProtocol = (DnsTransportProtocol)bR.ReadByte();
string tsigKeyName = bR.ReadShortString();
if (this is SOARecordInfo info)
{
if (zoneTransferProtocol != DnsTransportProtocol.Udp)
info.ZoneTransferProtocol = zoneTransferProtocol;
if (tsigKeyName.Length > 0)
info.TsigKeyName = tsigKeyName;
}
}
else if (version >= 6)
{
DnsTransportProtocol zoneTransferProtocol = (DnsTransportProtocol)bR.ReadByte();
string tsigKeyName = bR.ReadShortString();
_ = bR.ReadShortString(); //_tsigSharedSecret (obsolete)
_ = bR.ReadShortString(); //_tsigAlgorithm (obsolete)
if (this is SOARecordInfo info)
{
if (zoneTransferProtocol != DnsTransportProtocol.Udp)
info.ZoneTransferProtocol = zoneTransferProtocol;
if (tsigKeyName.Length > 0)
info.TsigKeyName = tsigKeyName;
}
}
if (version >= 8)
{
bool useSoaSerialDateScheme = bR.ReadBoolean();
if (this is SOARecordInfo info)
info.UseSoaSerialDateScheme = useSoaSerialDateScheme;
}
}
if (version >= 7)
{
_zoneTransferProtocol = (DnsTransportProtocol)bR.ReadByte();
_tsigKeyName = bR.ReadShortString();
}
else if (version >= 6)
{
_zoneTransferProtocol = (DnsTransportProtocol)bR.ReadByte();
_tsigKeyName = bR.ReadShortString();
_ = bR.ReadShortString(); //_tsigSharedSecret (obsolete)
_ = bR.ReadShortString(); //_tsigAlgorithm (obsolete)
}
if (version >= 8)
_useSoaSerialDateScheme = bR.ReadBoolean();
break;
default:
@@ -164,144 +226,21 @@ namespace DnsServerCore.Dns.ResourceRecords
#endregion
#region protected
protected abstract void ReadRecordInfoFrom(BinaryReader bR);
protected abstract void WriteRecordInfoTo(BinaryWriter bW);
#endregion
#region public
public void WriteTo(BinaryWriter bW)
{
bW.Write((byte)8); //version
bW.Write(_disabled);
bW.Write((byte)9); //version
if (_glueRecords is null)
{
bW.Write((byte)0);
}
else
{
bW.Write(Convert.ToByte(_glueRecords.Count));
foreach (DnsResourceRecord glueRecord in _glueRecords)
glueRecord.WriteTo(bW.BaseStream);
}
if (string.IsNullOrEmpty(_comments))
bW.Write((byte)0);
else
bW.WriteShortString(_comments);
bW.Write(_deletedOn);
if (_primaryNameServers is null)
{
bW.Write((byte)0);
}
else
{
bW.Write(Convert.ToByte(_primaryNameServers.Count));
foreach (NameServerAddress nameServer in _primaryNameServers)
nameServer.WriteTo(bW);
}
bW.Write((byte)_zoneTransferProtocol);
bW.WriteShortString(_tsigKeyName);
bW.Write(_useSoaSerialDateScheme);
}
#endregion
#region properties
public bool Disabled
{
get { return _disabled; }
set { _disabled = value; }
}
public IReadOnlyList<DnsResourceRecord> GlueRecords
{
get { return _glueRecords; }
set
{
if ((value is null) || (value.Count == 0))
_glueRecords = null;
else
_glueRecords = value;
}
}
public string Comments
{
get { return _comments; }
set
{
if ((value is not null) && (value.Length > 255))
throw new ArgumentOutOfRangeException(nameof(Comments), "Resource record comment text cannot exceed 255 characters.");
_comments = value;
}
}
public DateTime DeletedOn
{
get { return _deletedOn; }
set { _deletedOn = value; }
}
public IReadOnlyList<NameServerAddress> PrimaryNameServers
{
get { return _primaryNameServers; }
set
{
if ((value is null) || (value.Count == 0))
_primaryNameServers = null;
else
_primaryNameServers = value;
}
}
public DnsTransportProtocol ZoneTransferProtocol
{
get { return _zoneTransferProtocol; }
set
{
switch (value)
{
case DnsTransportProtocol.Tcp:
case DnsTransportProtocol.Tls:
case DnsTransportProtocol.Quic:
_zoneTransferProtocol = value;
break;
default:
throw new NotSupportedException("Zone transfer protocol is not supported: XFR-over-" + value.ToString().ToUpper());
}
}
}
public string TsigKeyName
{
get { return _tsigKeyName; }
set
{
if (value is null)
_tsigKeyName = string.Empty;
else
_tsigKeyName = value;
}
}
public bool UseSoaSerialDateScheme
{
get { return _useSoaSerialDateScheme; }
set { _useSoaSerialDateScheme = value; }
}
public DateTime LastUsedOn
{
get { return _lastUsedOn; }
set { _lastUsedOn = value; }
WriteRecordInfoTo(bW);
}
#endregion

View File

@@ -1,6 +1,6 @@
/*
Technitium DNS Server
Copyright (C) 2023 Shreyas Zare (shreyas@technitium.com)
Copyright (C) 2024 Shreyas Zare (shreyas@technitium.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -53,7 +53,7 @@ namespace DnsServerCore.Dns.ResourceRecords
}
}
record.GetAuthRecordInfo().GlueRecords = glueRecords;
record.GetAuthNSRecordInfo().GlueRecords = glueRecords;
}
public static void SyncGlueRecords(this DnsResourceRecord record, IReadOnlyList<DnsResourceRecord> allGlueRecords)
@@ -78,7 +78,7 @@ namespace DnsServerCore.Dns.ResourceRecords
}
}
record.GetAuthRecordInfo().GlueRecords = foundGlueRecords;
record.GetAuthNSRecordInfo().GlueRecords = foundGlueRecords;
}
public static void SyncGlueRecords(this DnsResourceRecord record, IReadOnlyCollection<DnsResourceRecord> deletedGlueRecords, IReadOnlyCollection<DnsResourceRecord> addedGlueRecords)
@@ -89,7 +89,7 @@ namespace DnsServerCore.Dns.ResourceRecords
bool updated = false;
List<DnsResourceRecord> updatedGlueRecords = new List<DnsResourceRecord>();
IReadOnlyList<DnsResourceRecord> existingGlueRecords = record.GetAuthRecordInfo().GlueRecords;
IReadOnlyList<DnsResourceRecord> existingGlueRecords = record.GetAuthNSRecordInfo().GlueRecords;
if (existingGlueRecords is not null)
{
foreach (DnsResourceRecord existingGlueRecord in existingGlueRecords)
@@ -119,18 +119,123 @@ namespace DnsServerCore.Dns.ResourceRecords
}
if (updated)
record.GetAuthRecordInfo().GlueRecords = updatedGlueRecords;
record.GetAuthNSRecordInfo().GlueRecords = updatedGlueRecords;
}
public static AuthRecordInfo GetAuthRecordInfo(this DnsResourceRecord record)
public static GenericRecordInfo GetAuthGenericRecordInfo(this DnsResourceRecord record)
{
if (record.Tag is not AuthRecordInfo rrInfo)
if (record.Tag is null)
{
rrInfo = new AuthRecordInfo();
record.Tag = rrInfo;
}
GenericRecordInfo rrInfo;
return rrInfo;
switch (record.Type)
{
case DnsResourceRecordType.NS:
rrInfo = new NSRecordInfo();
break;
case DnsResourceRecordType.SOA:
rrInfo = new SOARecordInfo();
break;
case DnsResourceRecordType.SVCB:
case DnsResourceRecordType.HTTPS:
rrInfo = new SVCBRecordInfo();
break;
default:
rrInfo = new GenericRecordInfo();
break;
}
record.Tag = rrInfo;
return rrInfo;
}
else if (record.Tag is GenericRecordInfo rrInfo)
{
return rrInfo;
}
else
{
throw new InvalidOperationException();
}
}
public static NSRecordInfo GetAuthNSRecordInfo(this DnsResourceRecord record)
{
if (record.Tag is null)
{
NSRecordInfo info = new NSRecordInfo();
record.Tag = info;
return info;
}
else if (record.Tag is NSRecordInfo nsInfo)
{
return nsInfo;
}
else
{
throw new InvalidOperationException();
}
}
public static SOARecordInfo GetAuthSOARecordInfo(this DnsResourceRecord record)
{
if (record.Tag is null)
{
SOARecordInfo info = new SOARecordInfo();
record.Tag = info;
return info;
}
else if (record.Tag is SOARecordInfo soaInfo)
{
return soaInfo;
}
else
{
throw new InvalidOperationException();
}
}
public static SVCBRecordInfo GetAuthSVCBRecordInfo(this DnsResourceRecord record)
{
if (record.Tag is null)
{
SVCBRecordInfo info = new SVCBRecordInfo();
record.Tag = info;
return info;
}
else if (record.Tag is SVCBRecordInfo svcbInfo)
{
return svcbInfo;
}
else
{
throw new InvalidOperationException();
}
}
public static HistoryRecordInfo GetAuthHistoryRecordInfo(this DnsResourceRecord record)
{
if (record.Tag is null)
{
HistoryRecordInfo info = new HistoryRecordInfo();
record.Tag = info;
return info;
}
else if (record.Tag is HistoryRecordInfo info)
{
return info;
}
else
{
throw new InvalidOperationException();
}
}
public static CacheRecordInfo GetCacheRecordInfo(this DnsResourceRecord record)

View File

@@ -0,0 +1,121 @@
/*
Technitium DNS Server
Copyright (C) 2024 Shreyas Zare (shreyas@technitium.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.IO;
using TechnitiumLibrary.IO;
namespace DnsServerCore.Dns.ResourceRecords
{
class GenericRecordInfo : AuthRecordInfo
{
#region variables
bool _disabled;
string _comments;
DateTime _lastUsedOn; //not serialized
#endregion
#region constructor
public GenericRecordInfo()
{ }
public GenericRecordInfo(BinaryReader bR)
: base(bR)
{ }
#endregion
#region protected
protected sealed override void ReadRecordInfoFrom(BinaryReader bR)
{
byte version = bR.ReadByte();
switch (version)
{
case 1:
_disabled = bR.ReadBoolean();
_comments = bR.ReadShortString();
ReadExtendedRecordInfoFrom(bR);
break;
default:
throw new InvalidDataException("GenericRecordInfo format version not supported.");
}
}
protected sealed override void WriteRecordInfoTo(BinaryWriter bW)
{
bW.Write((byte)1); //version
bW.Write(_disabled);
if (string.IsNullOrEmpty(_comments))
bW.Write((byte)0);
else
bW.WriteShortString(_comments);
WriteExtendedRecordInfoTo(bW);
}
protected virtual void ReadExtendedRecordInfoFrom(BinaryReader bR)
{
_ = bR.ReadByte(); //read byte to move ahead
}
protected virtual void WriteExtendedRecordInfoTo(BinaryWriter bW)
{
bW.Write((byte)0); //no extended info
}
#endregion
#region properties
public bool Disabled
{
get { return _disabled; }
set { _disabled = value; }
}
public string Comments
{
get { return _comments; }
set
{
if ((value is not null) && (value.Length > 255))
throw new ArgumentOutOfRangeException(nameof(Comments), "Resource record comment text cannot exceed 255 characters.");
_comments = value;
}
}
public DateTime LastUsedOn
{
get { return _lastUsedOn; }
set { _lastUsedOn = value; }
}
#endregion
}
}

View File

@@ -0,0 +1,89 @@
/*
Technitium DNS Server
Copyright (C) 2024 Shreyas Zare (shreyas@technitium.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.IO;
using TechnitiumLibrary.IO;
namespace DnsServerCore.Dns.ResourceRecords
{
class HistoryRecordInfo : AuthRecordInfo
{
#region variables
DateTime _deletedOn;
#endregion
#region constructor
public HistoryRecordInfo()
{ }
public HistoryRecordInfo(BinaryReader bR)
: base(bR)
{ }
#endregion
#region static
public static HistoryRecordInfo ReadFrom(BinaryReader bR)
{
return new HistoryRecordInfo(bR);
}
#endregion
#region protected
protected override void ReadRecordInfoFrom(BinaryReader bR)
{
byte version = bR.ReadByte();
switch (version)
{
case 1:
_deletedOn = bR.ReadDateTime();
break;
default:
throw new InvalidDataException("HistoryRecordInfo format version not supported.");
}
}
protected override void WriteRecordInfoTo(BinaryWriter bW)
{
bW.Write((byte)1); //version
bW.Write(_deletedOn);
}
#endregion
#region properties
public DateTime DeletedOn
{
get { return _deletedOn; }
set { _deletedOn = value; }
}
#endregion
}
}

View File

@@ -0,0 +1,109 @@
/*
Technitium DNS Server
Copyright (C) 2024 Shreyas Zare (shreyas@technitium.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.IO;
using TechnitiumLibrary.Net.Dns.ResourceRecords;
namespace DnsServerCore.Dns.ResourceRecords
{
class NSRecordInfo : GenericRecordInfo
{
#region variables
IReadOnlyList<DnsResourceRecord> _glueRecords;
#endregion
#region constructor
public NSRecordInfo()
{ }
public NSRecordInfo(BinaryReader bR)
: base(bR)
{ }
#endregion
#region protected
protected override void ReadExtendedRecordInfoFrom(BinaryReader bR)
{
byte version = bR.ReadByte();
switch (version)
{
case 0: //no extended info
break;
case 1:
int count = bR.ReadByte();
if (count > 0)
{
DnsResourceRecord[] glueRecords = new DnsResourceRecord[count];
for (int i = 0; i < glueRecords.Length; i++)
glueRecords[i] = new DnsResourceRecord(bR.BaseStream);
_glueRecords = glueRecords;
}
break;
default:
throw new InvalidDataException("NSRecordInfo format version not supported.");
}
}
protected override void WriteExtendedRecordInfoTo(BinaryWriter bW)
{
bW.Write((byte)1); //version
if (_glueRecords is null)
{
bW.Write((byte)0);
}
else
{
bW.Write(Convert.ToByte(_glueRecords.Count));
foreach (DnsResourceRecord glueRecord in _glueRecords)
glueRecord.WriteTo(bW.BaseStream);
}
}
#endregion
#region properties
public IReadOnlyList<DnsResourceRecord> GlueRecords
{
get { return _glueRecords; }
set
{
if ((value is null) || (value.Count == 0))
_glueRecords = null;
else
_glueRecords = value;
}
}
#endregion
}
}

View File

@@ -0,0 +1,158 @@
/*
Technitium DNS Server
Copyright (C) 2024 Shreyas Zare (shreyas@technitium.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.IO;
using TechnitiumLibrary.IO;
using TechnitiumLibrary.Net.Dns;
namespace DnsServerCore.Dns.ResourceRecords
{
class SOARecordInfo : GenericRecordInfo
{
#region variables
IReadOnlyList<NameServerAddress> _primaryNameServers;
DnsTransportProtocol _zoneTransferProtocol;
string _tsigKeyName = string.Empty;
bool _useSoaSerialDateScheme;
#endregion
#region constructor
public SOARecordInfo()
{ }
public SOARecordInfo(BinaryReader bR)
: base(bR)
{ }
#endregion
#region protected
protected override void ReadExtendedRecordInfoFrom(BinaryReader bR)
{
byte version = bR.ReadByte();
switch (version)
{
case 0: //no extended info
break;
case 1:
int count = bR.ReadByte();
if (count > 0)
{
NameServerAddress[] primaryNameServers = new NameServerAddress[count];
for (int i = 0; i < primaryNameServers.Length; i++)
primaryNameServers[i] = new NameServerAddress(bR);
_primaryNameServers = primaryNameServers;
}
_zoneTransferProtocol = (DnsTransportProtocol)bR.ReadByte();
_tsigKeyName = bR.ReadShortString();
_useSoaSerialDateScheme = bR.ReadBoolean();
break;
default:
throw new InvalidDataException("SOARecordInfo format version not supported.");
}
}
protected override void WriteExtendedRecordInfoTo(BinaryWriter bW)
{
bW.Write((byte)1); //version
if (_primaryNameServers is null)
{
bW.Write((byte)0);
}
else
{
bW.Write(Convert.ToByte(_primaryNameServers.Count));
foreach (NameServerAddress nameServer in _primaryNameServers)
nameServer.WriteTo(bW);
}
bW.Write((byte)_zoneTransferProtocol);
bW.WriteShortString(_tsigKeyName);
bW.Write(_useSoaSerialDateScheme);
}
#endregion
#region properties
public IReadOnlyList<NameServerAddress> PrimaryNameServers
{
get { return _primaryNameServers; }
set
{
if ((value is null) || (value.Count == 0))
_primaryNameServers = null;
else
_primaryNameServers = value;
}
}
public DnsTransportProtocol ZoneTransferProtocol
{
get { return _zoneTransferProtocol; }
set
{
switch (value)
{
case DnsTransportProtocol.Tcp:
case DnsTransportProtocol.Tls:
case DnsTransportProtocol.Quic:
_zoneTransferProtocol = value;
break;
default:
throw new NotSupportedException("Zone transfer protocol is not supported: XFR-over-" + value.ToString().ToUpper());
}
}
}
public string TsigKeyName
{
get { return _tsigKeyName; }
set
{
if (value is null)
_tsigKeyName = string.Empty;
else
_tsigKeyName = value;
}
}
public bool UseSoaSerialDateScheme
{
get { return _useSoaSerialDateScheme; }
set { _useSoaSerialDateScheme = value; }
}
#endregion
}
}

View File

@@ -0,0 +1,90 @@
/*
Technitium DNS Server
Copyright (C) 2024 Shreyas Zare (shreyas@technitium.com)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.IO;
namespace DnsServerCore.Dns.ResourceRecords
{
class SVCBRecordInfo : GenericRecordInfo
{
#region variables
bool _autoIpv4Hint;
bool _autoIpv6Hint;
#endregion
#region constructor
public SVCBRecordInfo()
{ }
public SVCBRecordInfo(BinaryReader bR)
: base(bR)
{ }
#endregion
#region protected
protected override void ReadExtendedRecordInfoFrom(BinaryReader bR)
{
byte version = bR.ReadByte();
switch (version)
{
case 0: //no extended info
break;
case 1:
_autoIpv4Hint = bR.ReadBoolean();
_autoIpv6Hint = bR.ReadBoolean();
break;
default:
throw new InvalidDataException("SVCBRecordInfo format version not supported.");
}
}
protected override void WriteExtendedRecordInfoTo(BinaryWriter bW)
{
bW.Write((byte)1); //version
bW.Write(_autoIpv4Hint);
bW.Write(_autoIpv6Hint);
}
#endregion
#region properties
public bool AutoIpv4Hint
{
get { return _autoIpv4Hint; }
set { _autoIpv4Hint = value; }
}
public bool AutoIpv6Hint
{
get { return _autoIpv6Hint; }
set { _autoIpv6Hint = value; }
}
#endregion
}
}