-
Notifications
You must be signed in to change notification settings - Fork 1k
Expand file tree
/
Copy pathDatagramDnsQueryDecoder.cs
More file actions
86 lines (73 loc) · 2.98 KB
/
Copy pathDatagramDnsQueryDecoder.cs
File metadata and controls
86 lines (73 loc) · 2.98 KB
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using DotNetty.Transport.Channels.Sockets;
using System;
using System.Collections.Generic;
using DotNetty.Transport.Channels;
using DotNetty.Codecs.DNS.Messages;
using DotNetty.Buffers;
using DotNetty.Codecs.DNS.Records;
namespace DotNetty.Codecs.DNS
{
public class DatagramDnsQueryDecoder : MessageToMessageDecoder<DatagramPacket>
{
private readonly IDnsRecordDecoder recordDecoder;
public DatagramDnsQueryDecoder() : this(new DefaultDnsRecordDecoder()) { }
public DatagramDnsQueryDecoder(IDnsRecordDecoder recordDecoder)
{
this.recordDecoder = recordDecoder ?? throw new ArgumentNullException(nameof(recordDecoder));
}
protected override void Decode(IChannelHandlerContext context, DatagramPacket message, List<object> output)
{
IByteBuffer buffer = message.Content;
IDnsQuery query = NewQuery(message, buffer);
bool success = false;
try
{
int questionCount = buffer.ReadUnsignedShort();
int answerCount = buffer.ReadUnsignedShort();
int authorityRecordCount = buffer.ReadUnsignedShort();
int additionalRecordCount = buffer.ReadUnsignedShort();
DecodeQuestions(query, buffer, questionCount);
DecodeRecords(query, DnsSection.ANSWER, buffer, answerCount);
DecodeRecords(query, DnsSection.AUTHORITY, buffer, authorityRecordCount);
DecodeRecords(query, DnsSection.ADDITIONAL, buffer, additionalRecordCount);
output.Add(query);
success = true;
}
finally
{
if (!success)
query.Release();
}
}
private static IDnsQuery NewQuery(DatagramPacket packet, IByteBuffer buffer)
{
int id = buffer.ReadUnsignedShort();
int flags = buffer.ReadUnsignedShort();
if (flags >> 15 == 1)
throw new CorruptedFrameException("not a query");
IDnsQuery query = new DatagramDnsQuery(
packet.Sender, packet.Recipient, id,
DnsOpCode.From((byte)(flags >> 11 & 0xf)));
query.IsRecursionDesired = (flags >> 8 & 1) == 1;
query.Z = flags >> 4 & 0x7;
return query;
}
private void DecodeQuestions(IDnsQuery query, IByteBuffer buffer, int questionCount)
{
for (int i = questionCount; i > 0; i--)
{
query.AddRecord(DnsSection.QUESTION, recordDecoder.DecodeQuestion(buffer));
}
}
private void DecodeRecords(IDnsQuery query, DnsSection section, IByteBuffer buffer, int count)
{
for (int i = count; i > 0; i--)
{
IDnsRecord r = recordDecoder.DecodeRecord(buffer);
if (r == null)
break;
query.AddRecord(section, r);
}
}
}
}