Skip to content

Commit

Permalink
Add EDNS support to DnsQueryEncoder
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
trustin committed Oct 16, 2014
1 parent 75ed693 commit 906d549
Showing 1 changed file with 33 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ protected void encode(ChannelHandlerContext ctx, DnsQuery query, List<Object> ou
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));
}
Expand All @@ -62,9 +65,9 @@ private static void encodeHeader(DnsHeader header, ByteBuf buf) {
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());
}

/**
Expand All @@ -79,13 +82,35 @@ private static void encodeHeader(DnsHeader header, ByteBuf buf) {
* 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(), '.');
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) {
buf.writeByte(part.length());
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
buf.writeShort(question.type().intValue());
buf.writeShort(question.dnsClass().intValue());
}
}

0 comments on commit 906d549

Please sign in to comment.