Skip to content

Commit

Permalink
Implement record pretty print. MDNS spec compliance improvements.
Browse files Browse the repository at this point in the history
  • Loading branch information
jdomnitz committed Jul 19, 2024
1 parent cd60eb1 commit f5ce1e3
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 25 deletions.
30 changes: 23 additions & 7 deletions TinyDNS/DNSResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,19 @@ public DNSResolver(List<IPAddress> nameservers, ResolutionMode mode = Resolution
this.globalNameservers.Add(nameserver);
}

public List<IPAddress> NameServers { get { return globalNameservers.ToList(); } }
public List<IPAddress> NameServers
{
get
{
return globalNameservers.ToList();
}
set
{
globalNameservers.Clear();
foreach (IPAddress nameserver in value)
globalNameservers.Add(nameserver);
}
}

private void ReloadNameservers()
{
Expand Down Expand Up @@ -70,7 +82,7 @@ public async Task<List<IPAddress>> ResolveHostV4(string hostname)
{
List<IPAddress> addresses = new List<IPAddress>();
Message? response = await ResolveQuery(new QuestionRecord(hostname, DNSRecordType.A, false));
if (response == null || response.ResponseCode != DNSStatus.OK || (response.Answers.Length == 0 && response.Additionals.Length == 0))
if (response == null || response.ResponseCode != DNSStatus.NoError || (response.Answers.Length == 0 && response.Additionals.Length == 0))
return addresses;

foreach (ResourceRecord answer in response.Answers)
Expand All @@ -90,7 +102,7 @@ public async Task<List<IPAddress>> ResolveHostV6(string hostname)
{
List<IPAddress> addresses = new List<IPAddress>();
Message? response = await ResolveQuery(new QuestionRecord(hostname, DNSRecordType.AAAA, false));
if (response == null || response.ResponseCode != DNSStatus.OK || (response.Answers.Length == 0 && response.Additionals.Length == 0))
if (response == null || response.ResponseCode != DNSStatus.NoError || (response.Answers.Length == 0 && response.Additionals.Length == 0))
return addresses;

foreach (ResourceRecord answer in response.Answers)
Expand All @@ -106,7 +118,7 @@ public async Task<List<IPAddress>> ResolveHostV6(string hostname)
return addresses;
}

public async Task<string?> ResolveIP(IPAddress address)
public async Task<Message?> ResolveIPRecord(IPAddress address)
{
byte[] addressBytes = address.GetAddressBytes();
List<string> host;
Expand All @@ -132,8 +144,12 @@ public async Task<List<IPAddress>> ResolveHostV6(string hostname)
host.Add("IP6");
host.Add("ARPA");
}
Message? response = await ResolveQuery(new QuestionRecord(host, DNSRecordType.PTR, false), privateQuery);
if (response == null || response.ResponseCode != DNSStatus.OK)
return await ResolveQuery(new QuestionRecord(host, DNSRecordType.PTR, false), privateQuery);
}
public async Task<string?> ResolveIP(IPAddress address)
{
Message? response = await ResolveIPRecord(address);
if (response == null || response.ResponseCode != DNSStatus.NoError)
return null;

foreach (ResourceRecord answer in response.Answers)
Expand Down Expand Up @@ -225,7 +241,7 @@ public async Task<List<IPAddress>> ResolveHostV6(string hostname)
return response;

//For any other error try a different nameserver
if (response.ResponseCode != DNSStatus.OK)
if (response.ResponseCode != DNSStatus.NoError)
continue;

//Add new info to the cache
Expand Down
12 changes: 6 additions & 6 deletions TinyDNS/Enums/DNSClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ namespace TinyDNS.Enums
{
public enum DNSClass : ushort
{
Reserved = 0,
Internet = 1,
Unassigned = 2,
RESERVED = 0,
IN = 1,
UNASSIGNED = 2,
CHAOS = 3,
Hesiod = 4,
None = 254,
Any = 255
HESIOD = 4,
NONE = 254,
ANY = 255
}
}
2 changes: 1 addition & 1 deletion TinyDNS/Enums/DNSStatus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public enum DNSStatus : byte
/// <summary>
/// No Error
/// </summary>
OK = 0,
NoError = 0,
/// <summary>
/// Format Error
/// </summary>
Expand Down
31 changes: 27 additions & 4 deletions TinyDNS/MDNS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@ private async Task ReceiveV4()
{
try
{
Memory<byte> buffer = new byte[9000];
Memory<byte> buffer = new byte[8972];
while (!stop.IsCancellationRequested)
{
try
{
SocketReceiveFromResult received = await listenerV4!.ReceiveFromAsync(buffer, SocketFlags.None, new IPEndPoint(IPAddress.Any, PORT), stop.Token);
Message msg = new Message(buffer.Slice(0, received.ReceivedBytes).Span);
if (msg.Response && msg.ResponseCode == DNSStatus.OK && (msg.Answers.Length > 0 || msg.Additionals.Length > 0))
if (msg.Response && msg.ResponseCode == DNSStatus.NoError && (msg.Answers.Length > 0 || msg.Additionals.Length > 0))
{
if (messageCache.Cached(msg, ((IPEndPoint)received.RemoteEndPoint).Address))
continue;
Expand All @@ -122,14 +122,14 @@ private async Task ReceiveV6()
{
try
{
Memory<byte> buffer = new byte[9000];
Memory<byte> buffer = new byte[8952];
while (!stop.IsCancellationRequested)
{
try
{
SocketReceiveFromResult received = await listenerV6!.ReceiveFromAsync(buffer, SocketFlags.None, new IPEndPoint(IPAddress.IPv6Any, PORT), stop.Token);
Message msg = new Message(buffer.Slice(0, received.ReceivedBytes).Span);
if (msg.Response && msg.ResponseCode == DNSStatus.OK && (msg.Answers.Length > 0 || msg.Additionals.Length > 0))
if (msg.Response && msg.ResponseCode == DNSStatus.NoError && (msg.Answers.Length > 0 || msg.Additionals.Length > 0))
{
if (messageCache.Cached(msg, ((IPEndPoint)received.RemoteEndPoint).Address))
continue;
Expand Down Expand Up @@ -189,9 +189,32 @@ public async Task QueryPointers(string domain)
await SendMessage(msg);
}

public async Task QueryIPv4Addresses(string domain)
{
Message msg = new Message();
msg.Response = false;
msg.Questions = [
new QuestionRecord(domain, DNSRecordType.A, false)
];
await SendMessage(msg);
}

public async Task QueryIPv6Addresses(string domain)
{
Message msg = new Message();
msg.Response = false;
msg.Questions = [
new QuestionRecord(domain, DNSRecordType.AAAA, false)
];
await SendMessage(msg);
}

private async Task SendMessage(Message msg)
{
Memory<byte> buffer = new byte[512];
msg.TransactionID = 0;
msg.RecursionDesired = false;
msg.RecursionAvailable = false;
int len = msg.ToBytes(buffer.Span);
foreach (Socket sender in senders)
{
Expand Down
50 changes: 50 additions & 0 deletions TinyDNS/Message.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using TinyDNS.Enums;
using TinyDNS.Records;
using System.Buffers.Binary;
using System.Text;

namespace TinyDNS
{
Expand Down Expand Up @@ -143,5 +144,54 @@ public override bool Equals(object? obj)
{
return Equals(obj as Message);
}

public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(";; Operation: ");
sb.Append(Operation);
sb.Append(", Status: ");
sb.Append(ResponseCode);
sb.Append(", ID: ");
sb.AppendLine(TransactionID.ToString());
sb.Append(";; Flags:");
if (Response)
sb.Append(" qr");
if (RecursionDesired)
sb.Append(" rd");
if (RecursionAvailable)
sb.Append(" ra");
sb.Append("; QUERY: ");
sb.Append(Questions.Length.ToString());
sb.Append(", ANSWER: ");
sb.Append(Answers.Length.ToString());
sb.Append(", AUTHORITY: ");
sb.Append(Authorities.Length.ToString());
sb.Append(", ADDITIONAL: ");
sb.AppendLine(Additionals.Length.ToString());
sb.AppendLine();
if (Questions.Length > 0)
{
sb.AppendLine(";; Questions:");
foreach (QuestionRecord question in Questions)
sb.AppendLine(question.ToString());
sb.AppendLine();
}
if (Answers.Length > 0)
{
sb.AppendLine(";; Answers:");
foreach (ResourceRecord answer in Answers)
sb.AppendLine(answer.ToString());
sb.AppendLine();
}
if (Authorities.Length > 0)
{
sb.AppendLine(";; Authority:");
foreach (ResourceRecord authority in Authorities)
sb.AppendLine(authority.ToString());
sb.AppendLine();
}
return sb.ToString();
}
}
}
5 changes: 5 additions & 0 deletions TinyDNS/Records/AAAARecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,10 @@ public override int GetHashCode()
{
return Address.GetHashCode() + (int)Type;
}

public override string ToString()
{
return base.ToString() + $"\t{Address}";
}
}
}
5 changes: 5 additions & 0 deletions TinyDNS/Records/ARecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,10 @@ public override int GetHashCode()
{
return Address.GetHashCode() + (int)Type;
}

public override string ToString()
{
return base.ToString() + $"\t{Address}";
}
}
}
5 changes: 5 additions & 0 deletions TinyDNS/Records/CNameRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,10 @@ public override bool Equals(ResourceRecord? other)
return base.Equals(other) && CNameLabels.SequenceEqual(otherCName.CNameLabels);
return false;
}

public override string ToString()
{
return base.ToString() + $"\t{CName}";
}
}
}
5 changes: 5 additions & 0 deletions TinyDNS/Records/NSRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,10 @@ public override bool Equals(ResourceRecord? other)
return base.Equals(other) && NSDomainLabels.SequenceEqual(otherNS.NSDomainLabels);
return false;
}

public override string ToString()
{
return base.ToString() + $"\t{NSDomain}";
}
}
}
5 changes: 5 additions & 0 deletions TinyDNS/Records/PtrRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,10 @@ public override bool Equals(ResourceRecord? other)
return base.Equals(other) && DomainLabels.SequenceEqual(otherPtr.DomainLabels);
return false;
}

public override string ToString()
{
return base.ToString() + $"\t{Domain}";
}
}
}
7 changes: 6 additions & 1 deletion TinyDNS/Records/QuestionRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public QuestionRecord(List<string> domain, DNSRecordType recordType, bool unicas
{
Name = domain;
Type = recordType;
Class = DNSClass.Internet;
Class = DNSClass.IN;
UnicastResponse = unicastResponse;
}

Expand Down Expand Up @@ -65,5 +65,10 @@ public override bool Equals(object? obj)
{
return Equals(obj as QuestionRecord);
}

public override string ToString()
{
return $"{string.Join('.',Name)}\t{Class}\t{Type}";
}
}
}
6 changes: 6 additions & 0 deletions TinyDNS/Records/ResourceRecord.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,11 @@ internal static ResourceRecord Parse(string line)
}
return record;
}

public override string ToString()
{
int ttl = (int)Math.Ceiling((Expires - DateTime.Now).TotalSeconds);
return $"{Name}\t{ttl}\t{Class}\t{Type}";
}
}
}
2 changes: 1 addition & 1 deletion TinyDNS/Records/ResourceRecordHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public ResourceRecordHeader(string[] columns)
Labels = DomainParser.Parse(columns[0]);
Type = DNSRecordParser.Parse(columns[2]);
uint ttl = uint.Parse(columns[1]);
Class = DNSClass.Internet;
Class = DNSClass.IN;
Expires = DateTime.Now + TimeSpan.FromSeconds(ttl);
}

Expand Down
10 changes: 5 additions & 5 deletions TinyDNS/TinyDNS.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
<TargetFrameworks>net80</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Version>0.5</Version>
<PackageLicenseExpression>AGPL-3.0-or-later</PackageLicenseExpression>
<PackageReadmeFile>README.md</PackageReadmeFile>
<Authors>jdomnitz</Authors>
<Company>SmartHomeOS and Contributors</Company>
<Version>0.5</Version>
<PackageLicenseExpression>AGPL-3.0-or-later</PackageLicenseExpression>
<PackageReadmeFile>README.md</PackageReadmeFile>
<Authors>jdomnitz</Authors>
<Company>SmartHomeOS and Contributors</Company>
</PropertyGroup>

<ItemGroup>
Expand Down

0 comments on commit f5ce1e3

Please sign in to comment.