1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.handler.codec.dns;
17
18 import io.netty5.buffer.api.Buffer;
19 import io.netty5.buffer.api.BufferAllocator;
20 import io.netty5.util.internal.UnstableApi;
21
22
23
24
25
26
27 @UnstableApi
28 public class DefaultDnsRecordDecoder implements DnsRecordDecoder {
29
30 static final String ROOT = ".";
31
32
33
34
35 protected DefaultDnsRecordDecoder() { }
36
37 @Override
38 public final DnsQuestion decodeQuestion(Buffer in) throws Exception {
39 String name = decodeName(in);
40 DnsRecordType type = DnsRecordType.valueOf(in.readUnsignedShort());
41 int qClass = in.readUnsignedShort();
42 return new DefaultDnsQuestion(name, type, qClass);
43 }
44
45 @Override
46 public final <T extends DnsRecord> T decodeRecord(BufferAllocator allocator, Buffer in) throws Exception {
47 final int startOffset = in.readerOffset();
48 final String name = decodeName(in);
49
50 final int endOffset = in.writerOffset();
51 if (endOffset - in.readerOffset() < 10) {
52
53 in.readerOffset(startOffset);
54 return null;
55 }
56
57 final DnsRecordType type = DnsRecordType.valueOf(in.readUnsignedShort());
58 final int aClass = in.readUnsignedShort();
59 final long ttl = in.readUnsignedInt();
60 final int length = in.readUnsignedShort();
61 final int offset = in.readerOffset();
62
63 if (endOffset - offset < length) {
64
65 in.readerOffset(startOffset);
66 return null;
67 }
68
69 @SuppressWarnings("unchecked")
70 T record = (T) decodeRecord(name, type, aClass, ttl, allocator, in, offset, length);
71 in.readerOffset(offset + length);
72 return record;
73 }
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 protected DnsRecord decodeRecord(
90 String name, DnsRecordType type, int dnsClass, long timeToLive,
91 BufferAllocator allocator, Buffer in, int offset, int length) throws Exception {
92
93
94
95
96
97 int roff = in.readerOffset();
98 int woff = in.writerOffset();
99 in.resetOffsets().writerOffset(offset + length).readerOffset(offset);
100 try {
101 if (type == DnsRecordType.PTR) {
102 return new DefaultDnsPtrRecord(
103 name, dnsClass, timeToLive, decodeName0(in));
104 }
105 if (type == DnsRecordType.CNAME || type == DnsRecordType.NS) {
106 return new DefaultDnsRawRecord(name, type, dnsClass, timeToLive,
107 DnsCodecUtil.decompressDomainName(allocator, in));
108 }
109 return new DefaultDnsRawRecord(
110 name, type, dnsClass, timeToLive, in.copy());
111 } finally {
112 in.resetOffsets().writerOffset(woff).readerOffset(roff);
113 }
114 }
115
116
117
118
119
120
121
122
123
124 protected String decodeName0(Buffer in) {
125 return decodeName(in);
126 }
127
128
129
130
131
132
133
134
135
136 public static String decodeName(Buffer in) {
137 return DnsCodecUtil.decodeDomainName(in);
138 }
139 }