Skip to content

Commit f7c2571

Browse files
committed
v0.6
Fix record cache eviction Documentation
1 parent 1179a58 commit f7c2571

File tree

7 files changed

+80
-18
lines changed

7 files changed

+80
-18
lines changed

TinyDNS/Cache/RecordCache.cs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,42 +19,44 @@ internal sealed class RecordCache
1919
{
2020
readonly int sizeLimit;
2121
readonly TimeSpan ttl;
22-
private readonly ConcurrentStack<RecordEntry> stack = new ConcurrentStack<RecordEntry>();
22+
private readonly ConcurrentQueue<RecordEntry> cache = new ConcurrentQueue<RecordEntry>();
2323

2424
public RecordCache(int sizeLimit, TimeSpan ttl)
2525
{
2626
this.sizeLimit = sizeLimit;
2727
this.ttl = ttl;
28-
2928
}
3029

3130
public void Clear()
3231
{
33-
stack.Clear();
32+
cache.Clear();
3433
}
3534

36-
public bool Cached(Message message, IPAddress endPoint)
35+
public bool Cached(Message message, IPAddress endPointIP)
3736
{
3837
Expire();
3938
RecordEntry entry = new RecordEntry();
4039
entry.message = message;
41-
entry.Address = endPoint;
40+
entry.Address = endPointIP;
4241
entry.Time = DateTime.Now;
43-
if (stack.Contains(entry))
44-
return true;
45-
stack.Push(entry);
46-
if (stack.Count > sizeLimit)
47-
stack.TryPop(out _);
42+
lock (cache)
43+
{
44+
if (cache.Contains(entry))
45+
return true;
46+
cache.Enqueue(entry);
47+
}
48+
if (cache.Count > sizeLimit)
49+
cache.TryDequeue(out _);
4850
return false;
4951
}
5052

5153
private void Expire()
5254
{
53-
while (stack.TryPeek(out RecordEntry entry))
55+
while (cache.TryPeek(out RecordEntry entry))
5456
{
5557
if (entry.Time + ttl > DateTime.Now)
5658
return;
57-
stack.TryPop(out _);
59+
cache.TryDequeue(out _);
5860
}
5961
}
6062
}

TinyDNS/Cache/RecordEntry.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,19 @@ internal struct RecordEntry : IEquatable<RecordEntry>
2222

2323
public bool Equals(RecordEntry other)
2424
{
25-
if (Address.Equals(other.Address))
26-
return message.Equals(other.message);
25+
return message.Equals(other.message);
26+
}
2727

28+
public override bool Equals(object? obj)
29+
{
30+
if (obj is RecordEntry entry)
31+
return Equals(entry);
2832
return false;
2933
}
34+
35+
public override int GetHashCode()
36+
{
37+
return message.GetHashCode();
38+
}
3039
}
3140
}

TinyDNS/DNSResolver.cs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,31 @@ public sealed class DNSResolver
2626
private readonly HashSet<IPAddress> globalNameservers = [];
2727
private ResolverCache cache = new ResolverCache();
2828
private ResolutionMode resolutionMode;
29+
/// <summary>
30+
/// Create a new DNS resolver
31+
/// </summary>
32+
/// <param name="mode">Which strategy to use to resolve queries</param>
2933
public DNSResolver(ResolutionMode mode = ResolutionMode.InsecureOnly)
3034
{
3135
this.resolutionMode = mode;
3236
ReloadNameservers();
3337
NetworkChange.NetworkAddressChanged += (s, e) => ReloadNameservers();
3438
}
35-
39+
/// <summary>
40+
/// Create a new DNS resolver
41+
/// </summary>
42+
/// <param name="nameservers">the nameservers to query</param>
43+
/// <param name="mode">Which strategy to use to resolve queries</param>
3644
public DNSResolver(List<IPAddress> nameservers, ResolutionMode mode = ResolutionMode.InsecureOnly)
3745
{
3846
this.resolutionMode = mode;
3947
foreach (IPAddress nameserver in nameservers)
4048
this.globalNameservers.Add(nameserver);
4149
}
4250

51+
/// <summary>
52+
/// The nameservers to query
53+
/// </summary>
4354
public List<IPAddress> NameServers
4455
{
4556
get
@@ -68,6 +79,11 @@ private void ReloadNameservers()
6879
}
6980
}
7081

82+
/// <summary>
83+
/// Resolve a hostname to it's IP addresses
84+
/// </summary>
85+
/// <param name="hostname">domain name</param>
86+
/// <returns>domain's IPs</returns>
7187
public async Task<List<IPAddress>> ResolveHost(string hostname)
7288
{
7389
ArgumentNullException.ThrowIfNullOrEmpty(hostname, nameof(hostname));
@@ -79,6 +95,11 @@ .. await ResolveHostV6(hostname)
7995
return addresses;
8096
}
8197

98+
/// <summary>
99+
/// Resolve a hostname to it's IP v4 addresses
100+
/// </summary>
101+
/// <param name="hostname">domain name</param>
102+
/// <returns>domain's IPs</returns>
82103
public async Task<List<IPAddress>> ResolveHostV4(string hostname)
83104
{
84105
ArgumentNullException.ThrowIfNullOrEmpty(hostname, nameof(hostname));
@@ -100,6 +121,11 @@ public async Task<List<IPAddress>> ResolveHostV4(string hostname)
100121
return addresses;
101122
}
102123

124+
/// <summary>
125+
/// Resolve a hostname to it's IPv6 addresses
126+
/// </summary>
127+
/// <param name="hostname">domain name</param>
128+
/// <returns>domain's IPs</returns>
103129
public async Task<List<IPAddress>> ResolveHostV6(string hostname)
104130
{
105131
ArgumentNullException.ThrowIfNullOrEmpty(hostname, nameof(hostname));
@@ -121,6 +147,12 @@ public async Task<List<IPAddress>> ResolveHostV6(string hostname)
121147
return addresses;
122148
}
123149

150+
/// <summary>
151+
/// Lookup the domain name for an IP address
152+
/// </summary>
153+
/// <param name="address"></param>
154+
/// <returns>The response message</returns>
155+
/// <exception cref="ArgumentNullException"></exception>
124156
public async Task<Message?> ResolveIPRecord(IPAddress address)
125157
{
126158
if (address == null)
@@ -129,6 +161,12 @@ public async Task<List<IPAddress>> ResolveHostV6(string hostname)
129161
bool privateQuery = IsPrivate(address, addressBytes);
130162
return await ResolveQuery(new QuestionRecord(DomainParser.FromIP(addressBytes), DNSRecordType.PTR, false), privateQuery);
131163
}
164+
165+
/// <summary>
166+
/// Lookup the domain name for an IP address
167+
/// </summary>
168+
/// <param name="address"></param>
169+
/// <returns>The domain</returns>
132170
public async Task<string?> ResolveIP(IPAddress address)
133171
{
134172
Message? response = await ResolveIPRecord(address);
@@ -143,6 +181,11 @@ public async Task<List<IPAddress>> ResolveHostV6(string hostname)
143181
return null;
144182
}
145183

184+
/// <summary>
185+
/// Sends a query and returns the response message
186+
/// </summary>
187+
/// <param name="question"></param>
188+
/// <returns></returns>
146189
public async Task<Message?> ResolveQuery(QuestionRecord question)
147190
{
148191
bool privateQuery = (question.Name.Last() == "local");

TinyDNS/DomainParser.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1212

1313
using System.Globalization;
14+
using System.Net;
1415
using System.Text;
1516

1617
namespace TinyDNS
@@ -108,6 +109,11 @@ public static List<string> Parse(string domain)
108109
return labels;
109110
}
110111

112+
internal static List<string> FromIP(IPAddress address)
113+
{
114+
return FromIP(address.GetAddressBytes());
115+
}
116+
111117
internal static List<string> FromIP(byte[] address)
112118
{
113119
List<string> host;

TinyDNS/MDNS.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ public async Task Query(List<string> domain, DNSRecordType type, bool unicastRes
208208

209209
public async Task<List<Message>> ResolveInverseQuery(IPAddress address, bool unicastResponse = false)
210210
{
211-
var domain = DomainParser.FromIP(address.GetAddressBytes());
211+
var domain = DomainParser.FromIP(address);
212212
List<Message> responses = new List<Message>();
213213
MessageEventHandler handler = delegate (DNSMessageEvent e)
214214
{

TinyDNS/Message.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,9 @@ public bool Equals(Message? other)
142142

143143
public override bool Equals(object? obj)
144144
{
145-
return Equals(obj as Message);
145+
if (obj is Message message)
146+
return Equals(message);
147+
return false;
146148
}
147149

148150
public override string ToString()

TinyDNS/TinyDNS.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<TargetFrameworks>net80</TargetFrameworks>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
7-
<Version>0.5</Version>
7+
<Version>0.6</Version>
88
<PackageLicenseExpression>AGPL-3.0-or-later</PackageLicenseExpression>
99
<PackageReadmeFile>README.md</PackageReadmeFile>
1010
<Authors>jdomnitz</Authors>

0 commit comments

Comments
 (0)