DnsNameResolver: makes possible to define additional records in DNS query

Motivation:

Current DnsNameResolver api don't allow to define additional records in DNS query.
It can be useful in many cases. For example when we want to query dns server with
real client address (EDNS-CLIENT-SUBNET extension:
http://tools.ietf.org/html/draft-vandergaast-edns-client-subnet-02 )

Modifications:

This change add new query methods with list of additional DnsRecord-s for query.

Result:

It is possible to create dns query with EDNS-CLIENT-SUBNET extension for example.
This commit is contained in:
Lukáš Karas 2016-02-13 14:06:06 +01:00 committed by Norman Maurer
parent c7aadb5469
commit b426566617
2 changed files with 58 additions and 16 deletions

View File

@ -29,6 +29,7 @@ import io.netty.channel.socket.DatagramChannel;
import io.netty.channel.socket.InternetProtocolFamily; import io.netty.channel.socket.InternetProtocolFamily;
import io.netty.handler.codec.dns.DatagramDnsQueryEncoder; import io.netty.handler.codec.dns.DatagramDnsQueryEncoder;
import io.netty.handler.codec.dns.DatagramDnsResponse; import io.netty.handler.codec.dns.DatagramDnsResponse;
import io.netty.handler.codec.dns.DnsRecord;
import io.netty.handler.codec.dns.DatagramDnsResponseDecoder; import io.netty.handler.codec.dns.DatagramDnsResponseDecoder;
import io.netty.handler.codec.dns.DnsQuestion; import io.netty.handler.codec.dns.DnsQuestion;
import io.netty.handler.codec.dns.DnsResponse; import io.netty.handler.codec.dns.DnsResponse;
@ -505,12 +506,20 @@ public class DnsNameResolver extends InetNameResolver {
return query(nextNameServerAddress(), question); return query(nextNameServerAddress(), question);
} }
/**
* Sends a DNS query with the specified question with additional records.
*/
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
DnsQuestion question, Iterable<DnsRecord> additional) {
return query(nextNameServerAddress(), question, additional);
}
/** /**
* Sends a DNS query with the specified question. * Sends a DNS query with the specified question.
*/ */
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query( public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
DnsQuestion question, Promise<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>> promise) { DnsQuestion question, Promise<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>> promise) {
return query(nextNameServerAddress(), question, promise); return query(nextNameServerAddress(), question, Collections.<DnsRecord>emptyList(), promise);
} }
private InetSocketAddress nextNameServerAddress() { private InetSocketAddress nextNameServerAddress() {
@ -523,9 +532,18 @@ public class DnsNameResolver extends InetNameResolver {
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query( public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
InetSocketAddress nameServerAddr, DnsQuestion question) { InetSocketAddress nameServerAddr, DnsQuestion question) {
return query0(checkNotNull(nameServerAddr, "nameServerAddr"), return query0(nameServerAddr, question, Collections.<DnsRecord>emptyList(),
checkNotNull(question, "question"), ch.eventLoop().<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>>newPromise());
ch.eventLoop().<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>>newPromise()); }
/**
* Sends a DNS query with the specified question with additional records using the specified name server list.
*/
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
InetSocketAddress nameServerAddr, DnsQuestion question, Iterable<DnsRecord> additional) {
return query0(nameServerAddr, question, additional,
ch.eventLoop().<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>>newPromise());
} }
/** /**
@ -535,18 +553,29 @@ public class DnsNameResolver extends InetNameResolver {
InetSocketAddress nameServerAddr, DnsQuestion question, InetSocketAddress nameServerAddr, DnsQuestion question,
Promise<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>> promise) { Promise<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>> promise) {
return query0(checkNotNull(nameServerAddr, "nameServerAddr"), return query0(nameServerAddr, question, Collections.<DnsRecord>emptyList(), promise);
checkNotNull(question, "question"), }
checkNotNull(promise, "promise"));
/**
* Sends a DNS query with the specified question with additional records using the specified name server list.
*/
public Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query(
InetSocketAddress nameServerAddr, DnsQuestion question,
Iterable<DnsRecord> additional,
Promise<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>> promise) {
return query0(nameServerAddr, question, additional, promise);
} }
private Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query0( private Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> query0(
InetSocketAddress nameServerAddr, DnsQuestion question, InetSocketAddress nameServerAddr, DnsQuestion question,
Iterable<DnsRecord> additional,
Promise<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>> promise) { Promise<AddressedEnvelope<? extends DnsResponse, InetSocketAddress>> promise) {
final Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> castPromise = cast(promise); final Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> castPromise = cast(
checkNotNull(promise, "promise"));
try { try {
new DnsQueryContext(this, nameServerAddr, question, castPromise).query(); new DnsQueryContext(this, nameServerAddr, question, additional, castPromise).query();
return castPromise; return castPromise;
} catch (Exception e) { } catch (Exception e) {
return castPromise.setFailure(e); return castPromise.setFailure(e);

View File

@ -35,8 +35,11 @@ import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.InternalLoggerFactory;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static io.netty.util.internal.ObjectUtil.checkNotNull;
final class DnsQueryContext { final class DnsQueryContext {
private static final InternalLogger logger = InternalLoggerFactory.getInstance(DnsQueryContext.class); private static final InternalLogger logger = InternalLoggerFactory.getInstance(DnsQueryContext.class);
@ -45,6 +48,7 @@ final class DnsQueryContext {
private final Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> promise; private final Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> promise;
private final int id; private final int id;
private final DnsQuestion question; private final DnsQuestion question;
private final Iterable<DnsRecord> additional;
private final DnsRecord optResource; private final DnsRecord optResource;
private final InetSocketAddress nameServerAddr; private final InetSocketAddress nameServerAddr;
@ -53,12 +57,15 @@ final class DnsQueryContext {
DnsQueryContext(DnsNameResolver parent, DnsQueryContext(DnsNameResolver parent,
InetSocketAddress nameServerAddr, InetSocketAddress nameServerAddr,
DnsQuestion question, Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> promise) { DnsQuestion question,
Iterable<DnsRecord> additional,
Promise<AddressedEnvelope<DnsResponse, InetSocketAddress>> promise) {
this.parent = parent; this.parent = checkNotNull(parent, "parent");
this.nameServerAddr = nameServerAddr; this.nameServerAddr = checkNotNull(nameServerAddr, "nameServerAddr");
this.question = question; this.question = checkNotNull(question, "question");
this.promise = promise; this.additional = checkNotNull(additional, "additional");
this.promise = checkNotNull(promise, "promise");
recursionDesired = parent.isRecursionDesired(); recursionDesired = parent.isRecursionDesired();
id = parent.queryContextManager.add(this); id = parent.queryContextManager.add(this);
@ -82,10 +89,16 @@ final class DnsQueryContext {
final DnsQuestion question = question(); final DnsQuestion question = question();
final InetSocketAddress nameServerAddr = nameServerAddr(); final InetSocketAddress nameServerAddr = nameServerAddr();
final DatagramDnsQuery query = new DatagramDnsQuery(null, nameServerAddr, id); final DatagramDnsQuery query = new DatagramDnsQuery(null, nameServerAddr, id);
query.setRecursionDesired(recursionDesired); query.setRecursionDesired(recursionDesired);
query.setRecord(DnsSection.QUESTION, question);
query.addRecord(DnsSection.QUESTION, question);
for (DnsRecord record:additional) {
query.addRecord(DnsSection.ADDITIONAL, record);
}
if (optResource != null) { if (optResource != null) {
query.setRecord(DnsSection.ADDITIONAL, optResource); query.addRecord(DnsSection.ADDITIONAL, optResource);
} }
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {