-
Notifications
You must be signed in to change notification settings - Fork 1k
Expand file tree
/
Copy pathDatagramDnsResponseDecoder.cs
More file actions
85 lines (73 loc) · 3.03 KB
/
Copy pathDatagramDnsResponseDecoder.cs
File metadata and controls
85 lines (73 loc) · 3.03 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
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 DatagramDnsResponseDecoder : MessageToMessageDecoder<DatagramPacket>
{
private readonly IDnsRecordDecoder recordDecoder;
public DatagramDnsResponseDecoder() : this(new DefaultDnsRecordDecoder()) { }
public DatagramDnsResponseDecoder(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;
IDnsResponse response = NewResponse(message, buffer);
bool success = false;
try
{
int questionCount = buffer.ReadUnsignedShort();
int answerCount = buffer.ReadUnsignedShort();
int authorityRecordCount = buffer.ReadUnsignedShort();
int additionalRecordCount = buffer.ReadUnsignedShort();
DecodeQuestions(response, buffer, questionCount);
DecodeRecords(response, DnsSection.ANSWER, buffer, answerCount);
DecodeRecords(response, DnsSection.AUTHORITY, buffer, authorityRecordCount);
DecodeRecords(response, DnsSection.ADDITIONAL, buffer, additionalRecordCount);
output.Add(response);
success = true;
}
finally
{
if (!success)
response.Release();
}
}
private static IDnsResponse NewResponse(DatagramPacket packet, IByteBuffer buffer)
{
int id = buffer.ReadUnsignedShort();
int flags = buffer.ReadUnsignedShort();
if (flags >> 15 == 0) throw new CorruptedFrameException("not a response");
IDnsResponse response = new DatagramDnsResponse(
packet.Sender,
packet.Recipient,
id,
DnsOpCode.From((byte)(flags >> 1 & 0xf)),
DnsResponseCode.From((byte)(flags & 0xf)));
return response;
}
private void DecodeQuestions(IDnsResponse response, IByteBuffer buffer, int questionCount)
{
for (int i = questionCount - 1; i > 0; i--)
{
response.AddRecord(DnsSection.QUESTION, recordDecoder.DecodeQuestion(buffer));
}
}
private void DecodeRecords(IDnsResponse response, DnsSection section, IByteBuffer buffer, int count)
{
for (int i = count - 1; i > 0; i--)
{
IDnsRecord r = recordDecoder.DecodeRecord(buffer);
if (r == null)
break;
response.AddRecord(section, r);
}
}
}
}