Add missing javadoc and review new code

This commit is contained in:
Rene Treffer 2014-06-22 15:29:51 +02:00
parent 028700efe0
commit 0e484dd17f
10 changed files with 205 additions and 7 deletions

View File

@ -5,8 +5,19 @@ package de.measite.minidns;
*/ */
public interface DNSCache { public interface DNSCache {
/**
* Add an an dns answer/response for a given dns question. Implementations
* should honor the ttl / receive timestamp.
* @param q The question.
* @param message The dns message.
*/
void put(Question q, DNSMessage message); void put(Question q, DNSMessage message);
/**
* Request a cached dns response.
* @param q The dns question.
* @return The dns message.
*/
DNSMessage get(Question q); DNSMessage get(Question q);
} }

View File

@ -4,39 +4,89 @@ import java.io.ByteArrayOutputStream;
import java.io.DataInputStream; import java.io.DataInputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import de.measite.minidns.Record.CLASS; import de.measite.minidns.Record.CLASS;
import de.measite.minidns.Record.TYPE; import de.measite.minidns.Record.TYPE;
import de.measite.minidns.util.NameUtil; import de.measite.minidns.util.NameUtil;
/**
* A DNS question (request).
*/
public class Question { public class Question {
/**
* The question string (e.g. "measite.de").
*/
private final String name; private final String name;
/**
* The question type (e.g. A).
*/
private final TYPE type; private final TYPE type;
/**
* The question class (usually IN / internet).
*/
private final CLASS clazz; private final CLASS clazz;
/**
* Cache for the serialized object.
*/
private byte[] byteArray; private byte[] byteArray;
/**
* Create a dns question for the given name/type/class.
* @param name The name e.g. "measite.de".
* @param type The type, e.g. A.
* @param clazz The class, usually IN (internet).
*/
public Question(String name, TYPE type, CLASS clazz) { public Question(String name, TYPE type, CLASS clazz) {
this.name = name; this.name = name;
this.type = type; this.type = type;
this.clazz = clazz; this.clazz = clazz;
} }
/**
* Create a dns question for the given name/type/IN (internet class).
* @param name The name e.g. "measite.de".
* @param type The type, e.g. A.
*/
public Question(String name, TYPE type) {
this(name, type, CLASS.IN);
}
/**
* Retrieve the type of this question.
* @return The type.
*/
public TYPE getType() { public TYPE getType() {
return type; return type;
} }
/**
* Retrieve the class of this dns question (usually internet).
* @return The class of this dns question.
*/
public CLASS getClazz() { public CLASS getClazz() {
return clazz; return clazz;
} }
/**
* Retrieve the name of this dns question (e.g. "measite.de").
* @return The name of this dns question.
*/
public String getName() { public String getName() {
return name; return name;
} }
/**
* Parse a byte array and rebuild the dns question from it.
* @param dis The input stream.
* @param data The plain data (for dns name references).
* @return The parsed dns question.
* @throws IOException On errors (read outside of packet).
*/
public static Question parse(DataInputStream dis, byte[] data) throws IOException { public static Question parse(DataInputStream dis, byte[] data) throws IOException {
String name = NameUtil.parse(dis, data); String name = NameUtil.parse(dis, data);
TYPE type = TYPE.getType(dis.readUnsignedShort()); TYPE type = TYPE.getType(dis.readUnsignedShort());
@ -44,6 +94,10 @@ public class Question {
return new Question (name, type, clazz); return new Question (name, type, clazz);
} }
/**
* Generate a binary paket for this dns question.
* @return The dns question.
*/
public byte[] toByteArray() { public byte[] toByteArray() {
if (byteArray == null) { if (byteArray == null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream(512); ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
@ -65,7 +119,7 @@ public class Question {
@Override @Override
public int hashCode() { public int hashCode() {
return toByteArray().hashCode(); return Arrays.hashCode(toByteArray());
} }
@Override @Override
@ -76,6 +130,8 @@ public class Question {
if (!(other instanceof Question)) { if (!(other instanceof Question)) {
return false; return false;
} }
return this.hashCode() == other.hashCode(); byte t[] = toByteArray();
byte o[] = ((Question)other).toByteArray();
return Arrays.equals(t, o);
} }
} }

View File

@ -286,10 +286,18 @@ public class Record {
(q.getName().equals(name)); (q.getName().equals(name));
} }
/**
* The generic record name, e.g. "measite.de".
* @return The record name.
*/
public String getName() { public String getName() {
return name; return name;
} }
/**
* The payload data, usually a subclass of data (A, AAAA, CNAME, ...).
* @return The payload data.
*/
public Data getPayload() { public Data getPayload() {
return payloadData; return payloadData;
} }

View File

@ -5,8 +5,14 @@ import java.io.IOException;
import de.measite.minidns.Record.TYPE; import de.measite.minidns.Record.TYPE;
/**
* A record payload (ip pointer).
*/
public class A implements Data { public class A implements Data {
/**
* Target IP.
*/
private byte[] ip; private byte[] ip;
@Override @Override

View File

@ -5,8 +5,14 @@ import java.io.IOException;
import de.measite.minidns.Record.TYPE; import de.measite.minidns.Record.TYPE;
/**
* AAAA payload (an ipv6 pointer).
*/
public class AAAA implements Data { public class AAAA implements Data {
/**
* The ipv6 address.
*/
private byte[] ip; private byte[] ip;
@Override @Override

View File

@ -6,6 +6,9 @@ import java.io.IOException;
import de.measite.minidns.Record.TYPE; import de.measite.minidns.Record.TYPE;
import de.measite.minidns.util.NameUtil; import de.measite.minidns.util.NameUtil;
/**
* CNAME payload (pointer to another domain / address).
*/
public class CNAME implements Data { public class CNAME implements Data {
protected String name; protected String name;
@ -20,8 +23,7 @@ public class CNAME implements Data {
@Override @Override
public byte[] toByteArray() { public byte[] toByteArray() {
// TODO Auto-generated method stub throw new UnsupportedOperationException("Not implemented yet");
return null;
} }
@Override @Override

View File

@ -5,12 +5,30 @@ import java.io.IOException;
import de.measite.minidns.Record.TYPE; import de.measite.minidns.Record.TYPE;
/**
* Generic payload class.
*/
public interface Data { public interface Data {
/**
* The payload type.
* @return The payload type.
*/
TYPE getType(); TYPE getType();
/**
* Binary representation of this payload.
* @return The binary representation of this payload.
*/
byte[] toByteArray(); byte[] toByteArray();
/**
* Parse this payload.
* @param dis The input stream.
* @param data The plain data (needed for name cross references).
* @param length The payload length.
* @throws IOException on io error (read past paket boundary).
*/
void parse(DataInputStream dis, byte data[], int length) throws IOException; void parse(DataInputStream dis, byte data[], int length) throws IOException;
} }

View File

@ -2,6 +2,9 @@ package de.measite.minidns.record;
import de.measite.minidns.Record.TYPE; import de.measite.minidns.Record.TYPE;
/**
* Nameserver record.
*/
public class NS extends CNAME { public class NS extends CNAME {
@Override @Override

View File

@ -6,49 +6,99 @@ import java.io.IOException;
import de.measite.minidns.Record.TYPE; import de.measite.minidns.Record.TYPE;
import de.measite.minidns.util.NameUtil; import de.measite.minidns.util.NameUtil;
/**
* SRV record payload (service pointer).
*/
public class SRV implements Data { public class SRV implements Data {
/**
* The priority of this service.
*/
protected int priority; protected int priority;
/**
* The weight of this service.
*/
protected int weight; protected int weight;
/**
* The target port.
*/
protected int port; protected int port;
/**
* The target server.
*/
protected String name; protected String name;
/**
* The priority of this service. Lower values mean higher priority.
* @return The priority.
*/
public int getPriority() { public int getPriority() {
return priority; return priority;
} }
/**
* Set the priority of this service entry. Lower values have higher priority.
* @param priority The new priority.
*/
public void setPriority(int priority) { public void setPriority(int priority) {
this.priority = priority; this.priority = priority;
} }
/**
* The weight of this service. Services with the same priority should be
* balanced based on weight.
* @return The weight of this service.
*/
public int getWeight() { public int getWeight() {
return weight; return weight;
} }
/**
* Set the weight of this service.
* @param weight The new weight of this service.
*/
public void setWeight(int weight) { public void setWeight(int weight) {
this.weight = weight; this.weight = weight;
} }
/**
* The target port of this service.
* @return The target port of this service.
*/
public int getPort() { public int getPort() {
return port; return port;
} }
/**
* Set the target port of this service.
* @param port The new target port.
*/
public void setPort(int port) { public void setPort(int port) {
this.port = port; this.port = port;
} }
/**
* The name of the target server.
* @return The target servers name.
*/
public String getName() { public String getName() {
return name; return name;
} }
/**
* Set the name of the target server.
* @param name The new target servers name.
*/
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
@Override @Override
public byte[] toByteArray() { public byte[] toByteArray() {
// TODO Auto-generated method stub throw new UnsupportedOperationException("Not implemented yet");
return null;
} }
@Override @Override

View File

@ -8,12 +8,28 @@ import java.net.IDN;
import java.util.HashSet; import java.util.HashSet;
import java.util.Arrays; import java.util.Arrays;
/**
* Utilities related to internationalized domain names and dns name handling.
*/
public class NameUtil { public class NameUtil {
/**
* Retrieve the rough binary length of a string
* (length + 2 bytes length prefix).
* @param name The name string.
* @return The binary size of the string (length + 2).
*/
public static int size(String name) { public static int size(String name) {
return name.length() + 2; return name.length() + 2;
} }
/**
* Check if two internationalized domain names are equal, possibly causing
* a serialization of both domain names.
* @param name1 The first domain name.
* @param name2 The second domain name.
* @return True if both domain names are the same.
*/
public static boolean idnEquals(String name1, String name2) { public static boolean idnEquals(String name1, String name2) {
if (name1 == name2) return true; // catches null, null if (name1 == name2) return true; // catches null, null
if (name1 == null) return false; if (name1 == null) return false;
@ -27,6 +43,12 @@ public class NameUtil {
} }
} }
/**
* Serialize a domain name under IDN rules.
* @param name The domain name.
* @return The binary domain name representation.
* @throws IOException Should never happen.
*/
public static byte[] toByteArray(String name) throws IOException { public static byte[] toByteArray(String name) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream(64); ByteArrayOutputStream baos = new ByteArrayOutputStream(64);
DataOutputStream dos = new DataOutputStream(baos); DataOutputStream dos = new DataOutputStream(baos);
@ -40,6 +62,14 @@ public class NameUtil {
return baos.toByteArray(); return baos.toByteArray();
} }
/**
* Parse a domain name starting at the current offset and moving the input
* stream pointer past this domain name (even if cross references occure).
* @param dis The input stream.
* @param data The raw data (for cross references).
* @return The domain name string.
* @throws IOException Should never happen.
*/
public static String parse(DataInputStream dis, byte data[]) public static String parse(DataInputStream dis, byte data[])
throws IOException throws IOException
{ {
@ -63,6 +93,14 @@ public class NameUtil {
return s; return s;
} }
/**
* Parse a domain name starting at the given offset.
* @param data The raw data.
* @param offset The offset.
* @param jumps The list of jumps (by now).
* @return The parsed domain name.
* @throws IllegalStateException on cycles.
*/
public static String parse( public static String parse(
byte data[], byte data[],
int offset, int offset,