diff --git a/DnsServerCore/Dns/ResourceRecords/CacheRecordInfo.cs b/DnsServerCore/Dns/ResourceRecords/CacheRecordInfo.cs
new file mode 100644
index 00000000..bcbaa383
--- /dev/null
+++ b/DnsServerCore/Dns/ResourceRecords/CacheRecordInfo.cs
@@ -0,0 +1,199 @@
+/*
+Technitium DNS Server
+Copyright (C) 2023 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 .
+
+*/
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using TechnitiumLibrary.Net;
+using TechnitiumLibrary.Net.Dns.ResourceRecords;
+
+namespace DnsServerCore.Dns.ResourceRecords
+{
+ class CacheRecordInfo
+ {
+ #region variables
+
+ public static readonly CacheRecordInfo Default = new CacheRecordInfo();
+
+ IReadOnlyList _glueRecords;
+ IReadOnlyList _rrsigRecords;
+ IReadOnlyList _nsecRecords;
+ NetworkAddress _eDnsClientSubnet;
+
+ DateTime _lastUsedOn; //not serialized
+
+ #endregion
+
+ #region constructor
+
+ public CacheRecordInfo()
+ { }
+
+ public CacheRecordInfo(BinaryReader bR)
+ {
+ byte version = bR.ReadByte();
+ switch (version)
+ {
+ case 1:
+ _glueRecords = ReadRecordsFrom(bR, true);
+ _rrsigRecords = ReadRecordsFrom(bR, false);
+ _nsecRecords = ReadRecordsFrom(bR, true);
+
+ if (bR.ReadBoolean())
+ _eDnsClientSubnet = NetworkAddress.ReadFrom(bR);
+
+ break;
+
+ default:
+ throw new InvalidDataException("CacheRecordInfo format version not supported.");
+ }
+ }
+
+ #endregion
+
+ #region private
+
+ private static IReadOnlyList ReadRecordsFrom(BinaryReader bR, bool includeInnerRRSigRecords)
+ {
+ int count = bR.ReadByte();
+ if (count == 0)
+ return null;
+
+ DnsResourceRecord[] records = new DnsResourceRecord[count];
+
+ for (int i = 0; i < count; i++)
+ {
+ records[i] = DnsResourceRecord.ReadCacheRecordFrom(bR, delegate (DnsResourceRecord record)
+ {
+ if (includeInnerRRSigRecords)
+ {
+ IReadOnlyList rrsigRecords = ReadRecordsFrom(bR, false);
+ if (rrsigRecords is not null)
+ record.GetCacheRecordInfo()._rrsigRecords = rrsigRecords;
+ }
+ });
+ }
+
+ return records;
+ }
+
+ private static void WriteRecordsTo(IReadOnlyList records, BinaryWriter bW, bool includeInnerRRSigRecords)
+ {
+ if (records is null)
+ {
+ bW.Write((byte)0);
+ }
+ else
+ {
+ bW.Write(Convert.ToByte(records.Count));
+
+ foreach (DnsResourceRecord record in records)
+ {
+ record.WriteCacheRecordTo(bW, delegate ()
+ {
+ if (includeInnerRRSigRecords)
+ {
+ if (record.Tag is CacheRecordInfo cacheRecordInfo)
+ WriteRecordsTo(cacheRecordInfo._rrsigRecords, bW, false);
+ else
+ bW.Write((byte)0);
+ }
+ });
+ }
+ }
+ }
+
+ #endregion
+
+ #region public
+
+ public void WriteTo(BinaryWriter bW)
+ {
+ bW.Write((byte)1); //version
+
+ WriteRecordsTo(_glueRecords, bW, true);
+ WriteRecordsTo(_rrsigRecords, bW, false);
+ WriteRecordsTo(_nsecRecords, bW, true);
+
+ if (_eDnsClientSubnet is null)
+ {
+ bW.Write(false);
+ }
+ else
+ {
+ bW.Write(true);
+ _eDnsClientSubnet.WriteTo(bW);
+ }
+ }
+
+ #endregion
+
+ #region properties
+
+ public IReadOnlyList GlueRecords
+ {
+ get { return _glueRecords; }
+ set
+ {
+ if ((value is null) || (value.Count == 0))
+ _glueRecords = null;
+ else
+ _glueRecords = value;
+ }
+ }
+
+ public IReadOnlyList RRSIGRecords
+ {
+ get { return _rrsigRecords; }
+ set
+ {
+ if ((value is null) || (value.Count == 0))
+ _rrsigRecords = null;
+ else
+ _rrsigRecords = value;
+ }
+ }
+
+ public IReadOnlyList NSECRecords
+ {
+ get { return _nsecRecords; }
+ set
+ {
+ if ((value is null) || (value.Count == 0))
+ _nsecRecords = null;
+ else
+ _nsecRecords = value;
+ }
+ }
+
+ public NetworkAddress EDnsClientSubnet
+ {
+ get { return _eDnsClientSubnet; }
+ set { _eDnsClientSubnet = value; }
+ }
+
+ public DateTime LastUsedOn
+ {
+ get { return _lastUsedOn; }
+ set { _lastUsedOn = value; }
+ }
+
+ #endregion
+ }
+}