/*
Technitium DNS Server
Copyright (C) 2020 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.Net;
using System.Net.Sockets;
using TechnitiumLibrary.Net.Dns;
using TechnitiumLibrary.Net.Dns.ResourceRecords;
namespace DnsServerCore.Dns.ResourceRecords
{
static class DnsResourceRecordExtension
{
public static void SetGlueRecords(this DnsResourceRecord record, IReadOnlyList glueRecords)
{
DnsResourceRecordInfo rrInfo = record.Tag as DnsResourceRecordInfo;
if (rrInfo == null)
{
rrInfo = new DnsResourceRecordInfo();
record.Tag = rrInfo;
}
rrInfo.GlueRecords = glueRecords;
}
public static void SetGlueRecords(this DnsResourceRecord record, string glueAddresses)
{
List addresses = new List();
foreach (string address in glueAddresses.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
addresses.Add(IPAddress.Parse(address.Trim()));
SetGlueRecords(record, addresses);
}
public static void SetGlueRecords(this DnsResourceRecord record, IReadOnlyList glueAddresses)
{
string domain;
switch (record.Type)
{
case DnsResourceRecordType.NS:
domain = (record.RDATA as DnsNSRecord).NameServer;
break;
case DnsResourceRecordType.SOA:
domain = (record.RDATA as DnsSOARecord).PrimaryNameServer;
break;
default:
throw new NotSupportedException();
}
DnsResourceRecord[] glueRecords = new DnsResourceRecord[glueAddresses.Count];
for (int i = 0; i < glueRecords.Length; i++)
{
switch (glueAddresses[i].AddressFamily)
{
case AddressFamily.InterNetwork:
glueRecords[i] = new DnsResourceRecord(domain, DnsResourceRecordType.A, DnsClass.IN, record.TtlValue, new DnsARecord(glueAddresses[i]));
break;
case AddressFamily.InterNetworkV6:
glueRecords[i] = new DnsResourceRecord(domain, DnsResourceRecordType.AAAA, DnsClass.IN, record.TtlValue, new DnsAAAARecord(glueAddresses[i]));
break;
}
}
SetGlueRecords(record, glueRecords);
}
public static void SyncGlueRecords(this DnsResourceRecord record, IReadOnlyList allGlueRecords)
{
string domain;
switch (record.Type)
{
case DnsResourceRecordType.NS:
domain = (record.RDATA as DnsNSRecord).NameServer;
break;
case DnsResourceRecordType.SOA:
domain = (record.RDATA as DnsSOARecord).PrimaryNameServer;
break;
default:
throw new NotSupportedException();
}
List foundGlueRecords = new List(2);
foreach (DnsResourceRecord glueRecord in allGlueRecords)
{
switch (glueRecord.Type)
{
case DnsResourceRecordType.A:
case DnsResourceRecordType.AAAA:
if (glueRecord.Name.Equals(domain, StringComparison.OrdinalIgnoreCase))
foundGlueRecords.Add(glueRecord);
break;
}
}
if (foundGlueRecords.Count > 0)
SetGlueRecords(record, foundGlueRecords);
}
public static IReadOnlyList GetGlueRecords(this DnsResourceRecord record)
{
DnsResourceRecordInfo rrInfo = record.Tag as DnsResourceRecordInfo;
if (rrInfo == null)
return Array.Empty();
IReadOnlyList glueRecords = rrInfo.GlueRecords;
if (glueRecords == null)
return Array.Empty();
return glueRecords;
}
public static IReadOnlyList GetGlueRecords(this IReadOnlyList records)
{
if (records.Count == 1)
return GetGlueRecords(records[0]);
List glueRecords = new List(records.Count * 2);
foreach (DnsResourceRecord nsRecord in records)
glueRecords.AddRange(GetGlueRecords(nsRecord));
return glueRecords;
}
public static bool IsDisabled(this DnsResourceRecord record)
{
DnsResourceRecordInfo rrInfo = record.Tag as DnsResourceRecordInfo;
if (rrInfo == null)
return false;
return rrInfo.Disabled;
}
public static void Disable(this DnsResourceRecord record)
{
DnsResourceRecordInfo rrInfo = record.Tag as DnsResourceRecordInfo;
if (rrInfo == null)
{
rrInfo = new DnsResourceRecordInfo();
record.Tag = rrInfo;
}
rrInfo.Disabled = true;
}
public static void Enable(this DnsResourceRecord record)
{
DnsResourceRecordInfo rrInfo = record.Tag as DnsResourceRecordInfo;
if (rrInfo == null)
return;
rrInfo.Disabled = false;
}
}
}