Add Cache to minidns
This commit is contained in:
parent
f66c0db63f
commit
7dd8cfc6e6
12
build.gradle
12
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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
||||
private byte[] byteArray;
|
||||
|
||||
public Question(String name, TYPE type, CLASS clazz) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public TYPE getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(TYPE type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public CLASS getClazz() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public void setClazz(CLASS clazz) {
|
||||
this.clazz = 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() throws IOException {
|
||||
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();
|
||||
return baos.toByteArray();
|
||||
} catch (IOException e) {
|
||||
// Should never happen
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
byteArray = baos.toByteArray();
|
||||
}
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue