Add missing javadoc and review new code
This commit is contained in:
parent
028700efe0
commit
0e484dd17f
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue