Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DNSSEC support + what else matters #23

Merged
merged 1 commit into from
Feb 1, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,6 @@ allprojects {
]
}

task compileAndroid(type: JavaCompile) {
source = compileJava.source
classpath = compileJava.classpath
destinationDir = new File(buildDir, 'android')
options.bootClasspath = androidBootClasspath
}

test { dependsOn compileAndroid }

checkstyle {
configFile = new File(rootConfigDir, 'checkstyle.xml')
}
Expand All @@ -138,6 +129,17 @@ allprojects {
}
}

configure(subprojects.findAll{!it.name.endsWith('-java7')}) {
task compileAndroid(type: JavaCompile) {
source = compileJava.source
classpath = compileJava.classpath
destinationDir = new File(buildDir, 'android')
options.bootClasspath = androidBootClasspath
}

test { dependsOn compileAndroid }
}

jar {
// Root project should not create empty jar artifact
enabled = false
Expand Down
155 changes: 97 additions & 58 deletions minidns-core/src/main/java/de/measite/minidns/AbstractDNSClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
*/
package de.measite.minidns;

import de.measite.minidns.Record.CLASS;
import de.measite.minidns.Record.TYPE;
import de.measite.minidns.source.DNSDataSource;
import de.measite.minidns.source.NetworkDataSource;

import java.io.IOException;
import java.net.InetAddress;
import java.security.NoSuchAlgorithmException;
Expand All @@ -18,9 +23,6 @@
import java.util.Random;
import java.util.logging.Logger;

import de.measite.minidns.Record.CLASS;
import de.measite.minidns.Record.TYPE;

/**
* A minimal DNS client for SRV/A/AAAA/NS and CNAME lookups, with IDN support.
* This circumvents the missing javax.naming package on android.
Expand All @@ -34,23 +36,15 @@ public abstract class AbstractDNSClient {
*/
protected final Random random;

/**
* The buffer size for dns replies.
*/
protected int bufferSize = 1500;

/**
* DNS timeout.
*/
protected int timeout = 5000;

/**
* The internal DNS cache.
*/
protected DNSCache cache;
protected DNSDataSource dataSource = new NetworkDataSource();

/**
* Create a new DNS client with the given DNS cache.
*
* @param cache The backend DNS cache.
*/
protected AbstractDNSClient(DNSCache cache) {
Expand All @@ -60,14 +54,20 @@ protected AbstractDNSClient(DNSCache cache) {

/**
* Creates a new client that uses the given Map as cache.
*
* @param cache the Map to use as cache for DNS results.
*/
protected AbstractDNSClient(final Map<Question, DNSMessage> cache) {
this();
if (cache != null)
this.cache = new DNSCache() {
public void put(Question q, DNSMessage message) { cache.put(q, message); }
public DNSMessage get(Question q) { return cache.get(q); }
public void put(Question q, DNSMessage message) {
cache.put(q, message);
}

public DNSMessage get(Question q) {
return cache.get(q);
}
};
}

Expand All @@ -84,36 +84,18 @@ protected AbstractDNSClient() {
this.random = random;
}

/**
* Retrieve the current dns query timeout, in milliseconds.
* @return the current dns query timeout in milliseconds.
*/
public int getTimeout() {
return timeout;
}

/**
* Change the dns query timeout for all future queries. The timeout
* must be specified in milliseconds.
* @param timeout new dns query timeout in milliseconds.
*/
public void setTimeout(int timeout) {
this.timeout = timeout;
}

/**
* Query the system nameservers for a single entry of any class.
*
* This can be used to determine the name server version, if name
* is version.bind, type is TYPE.TXT and clazz is CLASS.CH.
*
* @param name The DNS name to request.
* @param type The DNS type to request (SRV, A, AAAA, ...).
* @param name The DNS name to request.
* @param type The DNS type to request (SRV, A, AAAA, ...).
* @param clazz The class of the request (usually IN for Internet).
* @return The response (or null on timeout/error).
*/
public final DNSMessage query(String name, TYPE type, CLASS clazz)
{
public final DNSMessage query(String name, TYPE type, CLASS clazz) {
Question q = new Question(name, type, clazz);
return query(q);
}
Expand All @@ -126,66 +108,100 @@ public final DNSMessage query(String name, TYPE type, CLASS clazz)
* @param type The DNS type to request (SRV, A, AAAA, ...).
* @return The response (or null on timeout/error).
*/
public final DNSMessage query(String name, TYPE type)
{
public final DNSMessage query(String name, TYPE type) {
Question q = new Question(name, type, CLASS.IN);
return query(q);
}


/**
* Query the system DNS server for one entry.
*
* @param q The question section of the DNS query.
* @return The response (or null on timeout/error).
*/
public abstract DNSMessage query(Question q);

public DNSMessage query(Question q, InetAddress address, int port) {
// See if we have the answer to this question already cached
DNSMessage dnsMessage = (cache == null) ? null : cache.get(q);
if (dnsMessage != null) {
return dnsMessage;
}

DNSMessage message = buildMessage(q);

dnsMessage = dataSource.query(message, address, port);

if (dnsMessage == null) return null;

if (cache != null && isResponseCacheable(q, dnsMessage)) {
cache.put(q, dnsMessage);
}
return dnsMessage;
}

/**
* Query a specific server for one entry.
* @param q The question section of the DNS query.
* @param address The dns server address.
* @param port the dns port.
* @return The response (or null on timeout/error).
* @throws IOException On IOErrors.
* Whether a response from the DNS system should be cached or not.
*
* @param q The question the response message should answer.
* @param dnsMessage The response message received using the DNS client.
* @return True, if the response should be cached, false otherwise.
*/
protected boolean isResponseCacheable(Question q, DNSMessage dnsMessage) {
for (Record record : dnsMessage.getAnswers()) {
if (record.isAnswer(q)) {
return true;
}
}
return false;
}

/**
* Builds a {@link DNSMessage} object carrying the given Question.
*
* @param question {@link Question} to be put in the DNS request.
* @return A {@link DNSMessage} requesting the answer for the given Question.
*/
public abstract DNSMessage query(Question q, InetAddress address, int port) throws IOException;
protected abstract DNSMessage buildMessage(Question question);

/**
* Query a nameserver for a single entry.
* @param name The DNS name to request.
* @param type The DNS type to request (SRV, A, AAAA, ...).
* @param clazz The class of the request (usually IN for Internet).
*
* @param name The DNS name to request.
* @param type The DNS type to request (SRV, A, AAAA, ...).
* @param clazz The class of the request (usually IN for Internet).
* @param address The DNS server address.
* @param port The DNS server port.
* @param port The DNS server port.
* @return The response (or null on timeout / failure).
* @throws IOException On IO Errors.
*/
public DNSMessage query(String name, TYPE type, CLASS clazz, InetAddress address, int port)
throws IOException
{
throws IOException {
Question q = new Question(name, type, clazz);
return query(q, address, port);
}

/**
* Query a nameserver for a single entry.
* @param name The DNS name to request.
* @param type The DNS type to request (SRV, A, AAAA, ...).
* @param clazz The class of the request (usually IN for Internet).
*
* @param name The DNS name to request.
* @param type The DNS type to request (SRV, A, AAAA, ...).
* @param clazz The class of the request (usually IN for Internet).
* @param address The DNS server host.
* @return The response (or null on timeout / failure).
* @throws IOException On IO Errors.
*/
public DNSMessage query(String name, TYPE type, CLASS clazz, InetAddress address)
throws IOException
{
throws IOException {
Question q = new Question(name, type, clazz);
return query(q, address);
}

/**
* Query a specific server for one entry.
* @param q The question section of the DNS query.
*
* @param q The question section of the DNS query.
* @param host The dns server host.
* @return The response (or null on timeout/error).
* @throws IOException On IOErrors.
Expand All @@ -196,12 +212,35 @@ public DNSMessage query(Question q, String host) throws IOException {

/**
* Query a specific server for one entry.
* @param q The question section of the DNS query.
*
* @param q The question section of the DNS query.
* @param address The dns server address.
* @return The response (or null on timeout/error).
* @throws IOException On IOErrors.
*/
public DNSMessage query(Question q, InetAddress address) throws IOException {
return query(q, address, 53);
}

/**
* Returns the currently used {@link DNSDataSource}. See {@link #setDataSource(DNSDataSource)} for details.
*
* @return The currently used {@link DNSDataSource}
*/
public DNSDataSource getDataSource() {
return dataSource;
}

/**
* Set a {@link DNSDataSource} to be used by the DNSClient.
* The default implementation will direct all queries directly to the Internet.
*
* This can be used to define a non-default handling for outgoing data. This can be useful to redirect the requests
* to a proxy or to modify requests after or responses before they are handled by the DNSClient implementation.
*
* @param dataSource An implementation of DNSDataSource that shall be used.
*/
public void setDataSource(DNSDataSource dataSource) {
this.dataSource = dataSource;
}
}
Loading