aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Schmaus <flo@geekplace.eu>2014-06-12 09:29:35 +0200
committerFlorian Schmaus <flo@geekplace.eu>2014-06-12 09:52:41 +0200
commit7dd8cfc6e6cd9bafb2cb3a6fdc9866de7d7495a6 (patch)
tree5fb90e090cb52d754e5a8e561d488f1f96effab2
parentf66c0db63f0c0b65ad59ac1a8aaadc1cbaf40761 (diff)
Add Cache to minidns
-rw-r--r--build.gradle12
-rw-r--r--src/main/java/de/measite/minidns/Client.java43
-rw-r--r--src/main/java/de/measite/minidns/DNSMessage.java3
-rw-r--r--src/main/java/de/measite/minidns/Question.java73
4 files changed, 88 insertions, 43 deletions
diff --git a/build.gradle b/build.gradle
index 7cf46718..01eafc65 100644
--- a/build.gradle
+++ b/build.gradle
@@ -24,6 +24,18 @@ if (isSnapshot) {
version += '-SNAPSHOT'
}
+repositories {
+ mavenLocal()
+ mavenCentral()
+ maven {
+ url 'https://oss.sonatype.org/content/repositories/snapshots/'
+ }
+}
+
+dependencies {
+ compile 'org.igniterealtime.jxmpp:jxmpp-util-cache:0.1.0-alpha1-SNAPSHOT'
+}
+
jar {
manifest {
instruction 'Implementation-GitRevision:', project.ext.gitCommit
diff --git a/src/main/java/de/measite/minidns/Client.java b/src/main/java/de/measite/minidns/Client.java
index cad3902a..26e3ba01 100644
--- a/src/main/java/de/measite/minidns/Client.java
+++ b/src/main/java/de/measite/minidns/Client.java
@@ -17,6 +17,8 @@ import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
+import org.jxmpp.util.cache.ExpirationCache;
+
import de.measite.minidns.Record.CLASS;
import de.measite.minidns.Record.TYPE;
@@ -28,6 +30,9 @@ public class Client {
private static final Logger LOGGER = Logger.getLogger(Client.class.getName());
+ protected static final ExpirationCache<Question, DNSMessage> cache = new ExpirationCache<Question, DNSMessage>(
+ 10, 1000 * 60 * 60 * 24);
+
/**
* The internal random class for sequence generation.
*/
@@ -67,10 +72,7 @@ public class Client {
public DNSMessage query(String name, TYPE type, CLASS clazz, String host, int port)
throws IOException
{
- Question q = new Question();
- q.setClazz(clazz);
- q.setType(type);
- q.setName(name);
+ Question q = new Question(name, type, clazz);
return query(q, host, port);
}
@@ -86,10 +88,7 @@ public class Client {
public DNSMessage query(String name, TYPE type, CLASS clazz, String host)
throws IOException
{
- Question q = new Question();
- q.setClazz(clazz);
- q.setType(type);
- q.setName(name);
+ Question q = new Question(name, type, clazz);
return query(q, host);
}
@@ -102,10 +101,7 @@ public class Client {
*/
public DNSMessage query(String name, TYPE type, CLASS clazz)
{
- Question q = new Question();
- q.setClazz(clazz);
- q.setType(type);
- q.setName(name);
+ Question q = new Question(name, type, clazz);
return query(q);
}
@@ -127,6 +123,10 @@ public class Client {
* @throws IOException On IOErrors.
*/
public DNSMessage query(Question q, String host, int port) throws IOException {
+ DNSMessage dnsMessage = cache.get(q);
+ if (dnsMessage != null) {
+ return dnsMessage;
+ }
DNSMessage message = new DNSMessage();
message.setQuestions(new Question[]{q});
message.setRecursionDesired(true);
@@ -139,10 +139,16 @@ public class Client {
socket.send(packet);
packet = new DatagramPacket(new byte[bufferSize], bufferSize);
socket.receive(packet);
- DNSMessage dnsMessage = DNSMessage.parse(packet.getData());
+ dnsMessage = DNSMessage.parse(packet.getData());
if (dnsMessage.getId() != message.getId()) {
return null;
}
+ for (Record record : dnsMessage.getAnswers()) {
+ if (record.isAnswer(q)) {
+ cache.put(q, dnsMessage, record.ttl);
+ break;
+ }
+ }
return dnsMessage;
}
}
@@ -152,10 +158,19 @@ public class Client {
* @param q The question section of the DNS query.
*/
public DNSMessage query(Question q) {
+ // While this query method does in fact re-use query(Question, String)
+ // we still do a cache lookup here in order to avoid unnecessary
+ // findDNS()calls, which are expensive on Android. Note that we do not
+ // put the results back into the Cache, as this is already done by
+ // query(Question, String).
+ DNSMessage message = cache.get(q);
+ if (message != null) {
+ return message;
+ }
String dnsServer[] = findDNS();
for (String dns : dnsServer) {
try {
- DNSMessage message = query(q, dns);
+ message = query(q, dns);
if (message == null) {
continue;
}
diff --git a/src/main/java/de/measite/minidns/DNSMessage.java b/src/main/java/de/measite/minidns/DNSMessage.java
index 14c8f04b..ea1b25c8 100644
--- a/src/main/java/de/measite/minidns/DNSMessage.java
+++ b/src/main/java/de/measite/minidns/DNSMessage.java
@@ -416,8 +416,7 @@ public class DNSMessage {
int additionalResourceRecordCount = dis.readUnsignedShort();
message.questions = new Question[questionCount];
while (questionCount-- > 0) {
- Question q = new Question();
- q.parse(dis, data);
+ Question q = Question.parse(dis, data);
message.questions[questionCount] = q;
}
message.answers = new Record[answerCount];
diff --git a/src/main/java/de/measite/minidns/Question.java b/src/main/java/de/measite/minidns/Question.java
index 9d1e3f56..8efe19f1 100644
--- a/src/main/java/de/measite/minidns/Question.java
+++ b/src/main/java/de/measite/minidns/Question.java
@@ -11,52 +11,71 @@ import de.measite.minidns.util.NameUtil;
public class Question {
- private String name;
+ private final String name;
- private TYPE type;
+ private final TYPE type;
- private CLASS clazz = CLASS.IN;
+ private final CLASS clazz;
- public TYPE getType() {
- return type;
- }
+ private byte[] byteArray;
- public void setType(TYPE type) {
+ public Question(String name, TYPE type, CLASS clazz) {
+ this.name = name;
this.type = type;
+ this.clazz = clazz;
}
- public CLASS getClazz() {
- return clazz;
+ public TYPE getType() {
+ return type;
}
- public void setClazz(CLASS clazz) {
- this.clazz = clazz;
+ public CLASS getClazz() {
+ return clazz;
}
public String getName() {
return name;
}
- public void setName(String name) {
- this.name = name;
+ public static Question parse(DataInputStream dis, byte[] data) throws IOException {
+ String name = NameUtil.parse(dis, data);
+ TYPE type = TYPE.getType(dis.readUnsignedShort());
+ CLASS clazz = CLASS.getClass(dis.readUnsignedShort());
+ return new Question (name, type, clazz);
}
- public void parse(DataInputStream dis, byte[] data) throws IOException {
- this.name = NameUtil.parse(dis, data);
- this.type = TYPE.getType(dis.readUnsignedShort());
- this.clazz = CLASS.getClass(dis.readUnsignedShort());
+ public byte[] toByteArray() {
+ if (byteArray == null) {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
+ DataOutputStream dos = new DataOutputStream(baos);
+
+ try {
+ dos.write(NameUtil.toByteArray(this.name));
+ dos.writeShort(type.getValue());
+ dos.writeShort(clazz.getValue());
+ dos.flush();
+ } catch (IOException e) {
+ // Should never happen
+ throw new IllegalStateException(e);
+ }
+ byteArray = baos.toByteArray();
+ }
+ return byteArray;
}
- public byte[] toByteArray() throws IOException {
- ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
- DataOutputStream dos = new DataOutputStream(baos);
-
- dos.write(NameUtil.toByteArray(this.name));
- dos.writeShort(type.getValue());
- dos.writeShort(clazz.getValue());
-
- dos.flush();
- return baos.toByteArray();
+ @Override
+ public int hashCode() {
+ return toByteArray().hashCode();
}
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof Question)) {
+ return false;
+ }
+ return this.hashCode() == other.hashCode();
+ }
}