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'
|
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 {
|
jar {
|
||||||
manifest {
|
manifest {
|
||||||
instruction 'Implementation-GitRevision:', project.ext.gitCommit
|
instruction 'Implementation-GitRevision:', project.ext.gitCommit
|
||||||
|
|
|
@ -17,6 +17,8 @@ import java.util.Random;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.jxmpp.util.cache.ExpirationCache;
|
||||||
|
|
||||||
import de.measite.minidns.Record.CLASS;
|
import de.measite.minidns.Record.CLASS;
|
||||||
import de.measite.minidns.Record.TYPE;
|
import de.measite.minidns.Record.TYPE;
|
||||||
|
|
||||||
|
@ -28,6 +30,9 @@ public class Client {
|
||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(Client.class.getName());
|
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.
|
* 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)
|
public DNSMessage query(String name, TYPE type, CLASS clazz, String host, int port)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
Question q = new Question();
|
Question q = new Question(name, type, clazz);
|
||||||
q.setClazz(clazz);
|
|
||||||
q.setType(type);
|
|
||||||
q.setName(name);
|
|
||||||
return query(q, host, port);
|
return query(q, host, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,10 +88,7 @@ public class Client {
|
||||||
public DNSMessage query(String name, TYPE type, CLASS clazz, String host)
|
public DNSMessage query(String name, TYPE type, CLASS clazz, String host)
|
||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
Question q = new Question();
|
Question q = new Question(name, type, clazz);
|
||||||
q.setClazz(clazz);
|
|
||||||
q.setType(type);
|
|
||||||
q.setName(name);
|
|
||||||
return query(q, host);
|
return query(q, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,10 +101,7 @@ public class Client {
|
||||||
*/
|
*/
|
||||||
public DNSMessage query(String name, TYPE type, CLASS clazz)
|
public DNSMessage query(String name, TYPE type, CLASS clazz)
|
||||||
{
|
{
|
||||||
Question q = new Question();
|
Question q = new Question(name, type, clazz);
|
||||||
q.setClazz(clazz);
|
|
||||||
q.setType(type);
|
|
||||||
q.setName(name);
|
|
||||||
return query(q);
|
return query(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +123,10 @@ public class Client {
|
||||||
* @throws IOException On IOErrors.
|
* @throws IOException On IOErrors.
|
||||||
*/
|
*/
|
||||||
public DNSMessage query(Question q, String host, int port) throws IOException {
|
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();
|
DNSMessage message = new DNSMessage();
|
||||||
message.setQuestions(new Question[]{q});
|
message.setQuestions(new Question[]{q});
|
||||||
message.setRecursionDesired(true);
|
message.setRecursionDesired(true);
|
||||||
|
@ -139,10 +139,16 @@ public class Client {
|
||||||
socket.send(packet);
|
socket.send(packet);
|
||||||
packet = new DatagramPacket(new byte[bufferSize], bufferSize);
|
packet = new DatagramPacket(new byte[bufferSize], bufferSize);
|
||||||
socket.receive(packet);
|
socket.receive(packet);
|
||||||
DNSMessage dnsMessage = DNSMessage.parse(packet.getData());
|
dnsMessage = DNSMessage.parse(packet.getData());
|
||||||
if (dnsMessage.getId() != message.getId()) {
|
if (dnsMessage.getId() != message.getId()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
for (Record record : dnsMessage.getAnswers()) {
|
||||||
|
if (record.isAnswer(q)) {
|
||||||
|
cache.put(q, dnsMessage, record.ttl);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
return dnsMessage;
|
return dnsMessage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,10 +158,19 @@ public class Client {
|
||||||
* @param q The question section of the DNS query.
|
* @param q The question section of the DNS query.
|
||||||
*/
|
*/
|
||||||
public DNSMessage query(Question q) {
|
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();
|
String dnsServer[] = findDNS();
|
||||||
for (String dns : dnsServer) {
|
for (String dns : dnsServer) {
|
||||||
try {
|
try {
|
||||||
DNSMessage message = query(q, dns);
|
message = query(q, dns);
|
||||||
if (message == null) {
|
if (message == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -416,8 +416,7 @@ public class DNSMessage {
|
||||||
int additionalResourceRecordCount = dis.readUnsignedShort();
|
int additionalResourceRecordCount = dis.readUnsignedShort();
|
||||||
message.questions = new Question[questionCount];
|
message.questions = new Question[questionCount];
|
||||||
while (questionCount-- > 0) {
|
while (questionCount-- > 0) {
|
||||||
Question q = new Question();
|
Question q = Question.parse(dis, data);
|
||||||
q.parse(dis, data);
|
|
||||||
message.questions[questionCount] = q;
|
message.questions[questionCount] = q;
|
||||||
}
|
}
|
||||||
message.answers = new Record[answerCount];
|
message.answers = new Record[answerCount];
|
||||||
|
|
|
@ -11,52 +11,71 @@ import de.measite.minidns.util.NameUtil;
|
||||||
|
|
||||||
public class Question {
|
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() {
|
public TYPE getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setType(TYPE type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public CLASS getClazz() {
|
public CLASS getClazz() {
|
||||||
return clazz;
|
return clazz;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClazz(CLASS clazz) {
|
|
||||||
this.clazz = clazz;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public static Question parse(DataInputStream dis, byte[] data) throws IOException {
|
||||||
this.name = name;
|
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 {
|
public byte[] toByteArray() {
|
||||||
this.name = NameUtil.parse(dis, data);
|
if (byteArray == null) {
|
||||||
this.type = TYPE.getType(dis.readUnsignedShort());
|
|
||||||
this.clazz = CLASS.getClass(dis.readUnsignedShort());
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] toByteArray() throws IOException {
|
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
|
ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
|
||||||
DataOutputStream dos = new DataOutputStream(baos);
|
DataOutputStream dos = new DataOutputStream(baos);
|
||||||
|
|
||||||
|
try {
|
||||||
dos.write(NameUtil.toByteArray(this.name));
|
dos.write(NameUtil.toByteArray(this.name));
|
||||||
dos.writeShort(type.getValue());
|
dos.writeShort(type.getValue());
|
||||||
dos.writeShort(clazz.getValue());
|
dos.writeShort(clazz.getValue());
|
||||||
|
|
||||||
dos.flush();
|
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