AuthRecordInfo.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. Technitium DNS Server
  3. Copyright (C) 2024 Shreyas Zare (shreyas@technitium.com)
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. using System;
  16. using System.IO;
  17. using System.Net;
  18. using TechnitiumLibrary.IO;
  19. using TechnitiumLibrary.Net.Dns;
  20. using TechnitiumLibrary.Net.Dns.ResourceRecords;
  21. namespace DnsServerCore.Dns.ResourceRecords
  22. {
  23. abstract class AuthRecordInfo
  24. {
  25. #region constructor
  26. protected AuthRecordInfo()
  27. { }
  28. protected AuthRecordInfo(BinaryReader bR)
  29. {
  30. byte version = bR.ReadByte();
  31. if (version >= 9)
  32. ReadRecordInfoFrom(bR);
  33. else
  34. ReadOldFormatFrom(bR, version, this is SOARecordInfo);
  35. }
  36. #endregion
  37. #region static
  38. public static GenericRecordInfo ReadGenericRecordInfoFrom(BinaryReader bR, DnsResourceRecordType type)
  39. {
  40. switch (type)
  41. {
  42. case DnsResourceRecordType.NS:
  43. return new NSRecordInfo(bR);
  44. case DnsResourceRecordType.SOA:
  45. return new SOARecordInfo(bR);
  46. case DnsResourceRecordType.SVCB:
  47. case DnsResourceRecordType.HTTPS:
  48. return new SVCBRecordInfo(bR);
  49. default:
  50. return new GenericRecordInfo(bR);
  51. }
  52. }
  53. #endregion
  54. #region private
  55. private void ReadOldFormatFrom(BinaryReader bR, byte version, bool isSoa)
  56. {
  57. switch (version)
  58. {
  59. case 1:
  60. {
  61. bool disabled = bR.ReadBoolean();
  62. if (this is GenericRecordInfo info)
  63. info.Disabled = disabled;
  64. }
  65. break;
  66. case 2:
  67. case 3:
  68. case 4:
  69. case 5:
  70. case 6:
  71. case 7:
  72. case 8:
  73. {
  74. {
  75. bool disabled = bR.ReadBoolean();
  76. if (this is GenericRecordInfo info)
  77. info.Disabled = disabled;
  78. }
  79. if ((version < 5) && isSoa)
  80. {
  81. //read old glue records as NameServerAddress in case of SOA record
  82. int count = bR.ReadByte();
  83. if (count > 0)
  84. {
  85. NameServerAddress[] primaryNameServers = new NameServerAddress[count];
  86. for (int i = 0; i < primaryNameServers.Length; i++)
  87. {
  88. DnsResourceRecord glueRecord = new DnsResourceRecord(bR.BaseStream);
  89. IPAddress address;
  90. switch (glueRecord.Type)
  91. {
  92. case DnsResourceRecordType.A:
  93. address = (glueRecord.RDATA as DnsARecordData).Address;
  94. break;
  95. case DnsResourceRecordType.AAAA:
  96. address = (glueRecord.RDATA as DnsAAAARecordData).Address;
  97. break;
  98. default:
  99. continue;
  100. }
  101. primaryNameServers[i] = new NameServerAddress(address);
  102. }
  103. (this as SOARecordInfo).PrimaryNameServers = primaryNameServers;
  104. }
  105. }
  106. else
  107. {
  108. int count = bR.ReadByte();
  109. if (count > 0)
  110. {
  111. DnsResourceRecord[] glueRecords = new DnsResourceRecord[count];
  112. for (int i = 0; i < glueRecords.Length; i++)
  113. glueRecords[i] = new DnsResourceRecord(bR.BaseStream);
  114. if (this is NSRecordInfo info)
  115. info.GlueRecords = glueRecords;
  116. }
  117. }
  118. if (version >= 3)
  119. {
  120. string comments = bR.ReadShortString();
  121. if (this is GenericRecordInfo info)
  122. info.Comments = comments;
  123. }
  124. if (version >= 4)
  125. {
  126. DateTime deletedOn = bR.ReadDateTime();
  127. if (this is HistoryRecordInfo info)
  128. info.DeletedOn = deletedOn;
  129. }
  130. if (version >= 5)
  131. {
  132. int count = bR.ReadByte();
  133. if (count > 0)
  134. {
  135. NameServerAddress[] primaryNameServers = new NameServerAddress[count];
  136. for (int i = 0; i < primaryNameServers.Length; i++)
  137. primaryNameServers[i] = new NameServerAddress(bR);
  138. if (this is SOARecordInfo info)
  139. info.PrimaryNameServers = primaryNameServers;
  140. }
  141. }
  142. if (version >= 7)
  143. {
  144. DnsTransportProtocol zoneTransferProtocol = (DnsTransportProtocol)bR.ReadByte();
  145. string tsigKeyName = bR.ReadShortString();
  146. if (this is SOARecordInfo info)
  147. {
  148. if (zoneTransferProtocol != DnsTransportProtocol.Udp)
  149. info.ZoneTransferProtocol = zoneTransferProtocol;
  150. if (tsigKeyName.Length > 0)
  151. info.TsigKeyName = tsigKeyName;
  152. }
  153. }
  154. else if (version >= 6)
  155. {
  156. DnsTransportProtocol zoneTransferProtocol = (DnsTransportProtocol)bR.ReadByte();
  157. string tsigKeyName = bR.ReadShortString();
  158. _ = bR.ReadShortString(); //_tsigSharedSecret (obsolete)
  159. _ = bR.ReadShortString(); //_tsigAlgorithm (obsolete)
  160. if (this is SOARecordInfo info)
  161. {
  162. if (zoneTransferProtocol != DnsTransportProtocol.Udp)
  163. info.ZoneTransferProtocol = zoneTransferProtocol;
  164. if (tsigKeyName.Length > 0)
  165. info.TsigKeyName = tsigKeyName;
  166. }
  167. }
  168. if (version >= 8)
  169. {
  170. bool useSoaSerialDateScheme = bR.ReadBoolean();
  171. if (this is SOARecordInfo info)
  172. info.UseSoaSerialDateScheme = useSoaSerialDateScheme;
  173. }
  174. }
  175. break;
  176. default:
  177. throw new InvalidDataException("AuthRecordInfo format version not supported.");
  178. }
  179. }
  180. #endregion
  181. #region protected
  182. protected abstract void ReadRecordInfoFrom(BinaryReader bR);
  183. protected abstract void WriteRecordInfoTo(BinaryWriter bW);
  184. #endregion
  185. #region public
  186. public void WriteTo(BinaryWriter bW)
  187. {
  188. bW.Write((byte)9); //version
  189. WriteRecordInfoTo(bW);
  190. }
  191. #endregion
  192. }
  193. }