ForwarderSubDomainZone.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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.Collections.Generic;
  17. using TechnitiumLibrary.Net.Dns.ResourceRecords;
  18. namespace DnsServerCore.Dns.Zones
  19. {
  20. class ForwarderSubDomainZone : SubDomainZone
  21. {
  22. #region variables
  23. readonly ForwarderZone _forwarderZone;
  24. #endregion
  25. #region constructor
  26. public ForwarderSubDomainZone(ForwarderZone forwarderZone, string name)
  27. : base(forwarderZone, name)
  28. {
  29. _forwarderZone = forwarderZone;
  30. }
  31. #endregion
  32. #region public
  33. public override void SetRecords(DnsResourceRecordType type, IReadOnlyList<DnsResourceRecord> records)
  34. {
  35. switch (type)
  36. {
  37. case DnsResourceRecordType.SOA:
  38. throw new InvalidOperationException("Cannot set SOA record on sub domain.");
  39. case DnsResourceRecordType.DS:
  40. case DnsResourceRecordType.DNSKEY:
  41. case DnsResourceRecordType.RRSIG:
  42. case DnsResourceRecordType.NSEC:
  43. case DnsResourceRecordType.NSEC3PARAM:
  44. case DnsResourceRecordType.NSEC3:
  45. throw new InvalidOperationException("Cannot set DNSSEC records.");
  46. default:
  47. if (records[0].OriginalTtlValue > _forwarderZone.GetZoneSoaExpire())
  48. throw new DnsServerException("Failed to set records: TTL cannot be greater than SOA EXPIRE.");
  49. if (!TrySetRecords(type, records, out IReadOnlyList<DnsResourceRecord> deletedRecords))
  50. throw new DnsServerException("Failed to set records. Please try again.");
  51. _forwarderZone.CommitAndIncrementSerial(deletedRecords, records);
  52. _forwarderZone.TriggerNotify();
  53. break;
  54. }
  55. }
  56. public override void AddRecord(DnsResourceRecord record)
  57. {
  58. switch (record.Type)
  59. {
  60. case DnsResourceRecordType.DS:
  61. case DnsResourceRecordType.DNSKEY:
  62. case DnsResourceRecordType.RRSIG:
  63. case DnsResourceRecordType.NSEC:
  64. case DnsResourceRecordType.NSEC3PARAM:
  65. case DnsResourceRecordType.NSEC3:
  66. throw new InvalidOperationException("Cannot add DNSSEC record.");
  67. default:
  68. if (record.OriginalTtlValue > _forwarderZone.GetZoneSoaExpire())
  69. throw new DnsServerException("Failed to add record: TTL cannot be greater than SOA EXPIRE.");
  70. AddRecord(record, out IReadOnlyList<DnsResourceRecord> addedRecords, out IReadOnlyList<DnsResourceRecord> deletedRecords);
  71. if (addedRecords.Count > 0)
  72. {
  73. _forwarderZone.CommitAndIncrementSerial(deletedRecords, addedRecords);
  74. _forwarderZone.TriggerNotify();
  75. }
  76. break;
  77. }
  78. }
  79. public override bool DeleteRecords(DnsResourceRecordType type)
  80. {
  81. if (_entries.TryRemove(type, out IReadOnlyList<DnsResourceRecord> removedRecords))
  82. {
  83. _forwarderZone.CommitAndIncrementSerial(removedRecords);
  84. _forwarderZone.TriggerNotify();
  85. return true;
  86. }
  87. return false;
  88. }
  89. public override bool DeleteRecord(DnsResourceRecordType type, DnsResourceRecordData rdata)
  90. {
  91. if (TryDeleteRecord(type, rdata, out DnsResourceRecord deletedRecord))
  92. {
  93. _forwarderZone.CommitAndIncrementSerial([deletedRecord]);
  94. _forwarderZone.TriggerNotify();
  95. return true;
  96. }
  97. return false;
  98. }
  99. public override void UpdateRecord(DnsResourceRecord oldRecord, DnsResourceRecord newRecord)
  100. {
  101. switch (oldRecord.Type)
  102. {
  103. case DnsResourceRecordType.SOA:
  104. throw new InvalidOperationException("Cannot update record: use SetRecords() for " + oldRecord.Type.ToString() + " record.");
  105. default:
  106. if (oldRecord.Type != newRecord.Type)
  107. throw new InvalidOperationException("Old and new record types do not match.");
  108. if (newRecord.OriginalTtlValue > _forwarderZone.GetZoneSoaExpire())
  109. throw new DnsServerException("Failed to update record: TTL cannot be greater than SOA EXPIRE.");
  110. if (!TryDeleteRecord(oldRecord.Type, oldRecord.RDATA, out DnsResourceRecord deletedRecord))
  111. throw new InvalidOperationException("Cannot update record: the record does not exists to be updated.");
  112. AddRecord(newRecord, out IReadOnlyList<DnsResourceRecord> addedRecords, out IReadOnlyList<DnsResourceRecord> deletedRecords);
  113. List<DnsResourceRecord> allDeletedRecords = new List<DnsResourceRecord>(deletedRecords.Count + 1);
  114. allDeletedRecords.Add(deletedRecord);
  115. allDeletedRecords.AddRange(deletedRecords);
  116. _forwarderZone.CommitAndIncrementSerial(allDeletedRecords, addedRecords);
  117. _forwarderZone.TriggerNotify();
  118. break;
  119. }
  120. }
  121. #endregion
  122. }
  123. }