Add EDNS support to DnsQueryEncoder
Motivation: DnsQueryEncoder does not encode the 'additional resources' section at all, which contains the pseudo-RR as defined in RFC 2671. Modifications: - Modify DnsQueryEncoder to encode the additional resources - Fix a bug in DnsQueryEncoder where an empty name is encoded incorrectly Result: A user can send an EDNS query.
This commit is contained in:
parent
87c82d4845
commit
ab2e80fbb1
@ -40,7 +40,10 @@ public class DnsQueryEncoder extends MessageToMessageEncoder<DnsQuery> {
|
||||
encodeHeader(query.header(), buf);
|
||||
List<DnsQuestion> questions = query.questions();
|
||||
for (DnsQuestion question : questions) {
|
||||
encodeQuestion(question, CharsetUtil.UTF_8, buf);
|
||||
encodeQuestion(question, CharsetUtil.US_ASCII, buf);
|
||||
}
|
||||
for (DnsResource resource: query.additionalResources()) {
|
||||
encodeResource(resource, CharsetUtil.US_ASCII, buf);
|
||||
}
|
||||
out.add(new DatagramPacket(buf, query.recipient(), null));
|
||||
}
|
||||
@ -62,9 +65,9 @@ public class DnsQueryEncoder extends MessageToMessageEncoder<DnsQuery> {
|
||||
flags |= header.isRecursionDesired() ? 1 << 8 : 0;
|
||||
buf.writeShort(flags);
|
||||
buf.writeShort(header.questionCount());
|
||||
buf.writeShort(header.answerCount()); // Must be 0
|
||||
buf.writeShort(header.authorityResourceCount()); // Must be 0
|
||||
buf.writeShort(header.additionalResourceCount()); // Must be 0
|
||||
buf.writeShort(0); // answerCount
|
||||
buf.writeShort(0); // authorityResourceCount
|
||||
buf.writeShort(header.additionalResourceCount());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,13 +82,35 @@ public class DnsQueryEncoder extends MessageToMessageEncoder<DnsQuery> {
|
||||
* the buffer the encoded data should be written to
|
||||
*/
|
||||
private static void encodeQuestion(DnsQuestion question, Charset charset, ByteBuf buf) {
|
||||
String[] parts = StringUtil.split(question.name(), '.');
|
||||
for (String part: parts) {
|
||||
buf.writeByte(part.length());
|
||||
buf.writeBytes(part.getBytes(charset));
|
||||
}
|
||||
buf.writeByte(0); // marks end of name field
|
||||
encodeName(question.name(), charset, buf);
|
||||
buf.writeShort(question.type().intValue());
|
||||
buf.writeShort(question.dnsClass().intValue());
|
||||
}
|
||||
|
||||
private static void encodeResource(DnsResource resource, Charset charset, ByteBuf buf) {
|
||||
encodeName(resource.name(), charset, buf);
|
||||
|
||||
buf.writeShort(resource.type().intValue());
|
||||
buf.writeShort(resource.dnsClass().intValue());
|
||||
buf.writeInt((int) resource.timeToLive());
|
||||
|
||||
ByteBuf content = resource.content();
|
||||
int contentLen = content.readableBytes();
|
||||
|
||||
buf.writeShort(contentLen);
|
||||
buf.writeBytes(content, content.readerIndex(), contentLen);
|
||||
}
|
||||
|
||||
private static void encodeName(String name, Charset charset, ByteBuf buf) {
|
||||
String[] parts = StringUtil.split(name, '.');
|
||||
for (String part: parts) {
|
||||
final int partLen = part.length();
|
||||
if (partLen == 0) {
|
||||
continue;
|
||||
}
|
||||
buf.writeByte(partLen);
|
||||
buf.writeBytes(part.getBytes(charset));
|
||||
}
|
||||
buf.writeByte(0); // marks end of name field
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user