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