MailSharp / MailSharp.DNS / Resolver.Cache.cs
Code · 73 lines · 1776 bytes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73using System.Collections.Concurrent;

namespace MailSharp.DNS;

public partial class Resolver
{
	private readonly ConcurrentDictionary<string, List<RR>> recordCache = [];
	private Response? SearchInRecordCache(QuestionRecord question)
	{
		if (!useCache)
			return null;

		List<RR> list = [];
		if (recordCache.TryGetValue(question.Name, out List<RR>? value))
		{
			list = value.Where(x => x.TTL > 0 && x.Class == (DnsClass)question.Class &&
			(question.Type == DnsQType.ANY || x.Type == (DnsType)question.Type))
				.ToList();
		}
		if (list.Count == 0)
			return null;

		Response response = new()
		{
			Questions = [question],
			Authorities = list
		};

		response.Header.QDCount = (ushort)response.Questions.Count;
		response.Header.NSCount = (ushort)list.Count;
		return response;
	}

	private void AddToCache(Response response)
	{
		if (!useCache || response.Questions.Count == 0 || response.Header.RCODE != RCode.NoError)
			return;

		foreach (var rr in response.RecordsRR)
		{
			rr.TimeStamp = DateTime.Now;
			recordCache.AddOrUpdate(rr.Name,
				[rr],
				(_, list) =>
				{
					list.Add(rr);
					return list;
				});
		}
	}

	internal class QuestionComparer : IEqualityComparer<QuestionRecord>
	{
		public int GetHashCode(QuestionRecord obj)
		{
			int hash = 17;
			hash = hash * 31 + obj.Class.GetHashCode();
			hash = hash * 31 + obj.Type.GetHashCode();
			hash = hash * 31 + (obj.Name != null ? StringComparer.Ordinal.GetHashCode(obj.Name) : 0);
			return hash;
		}
		public bool Equals(QuestionRecord? x, QuestionRecord? y)
		{
			if(x == null || y == null)
				return false;
			if(x.Class != y.Class)
				return false;
			if (x.Type != y.Type)
				return false;
			return string.Equals(x.Name, y.Name, StringComparison.OrdinalIgnoreCase);
		}
	}
}