diff options
Diffstat (limited to 'libs/minidns/src/main/java/de/measite/minidns/Question.java')
-rw-r--r-- | libs/minidns/src/main/java/de/measite/minidns/Question.java | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/libs/minidns/src/main/java/de/measite/minidns/Question.java b/libs/minidns/src/main/java/de/measite/minidns/Question.java new file mode 100644 index 00000000..3b2fa1a1 --- /dev/null +++ b/libs/minidns/src/main/java/de/measite/minidns/Question.java @@ -0,0 +1,158 @@ +package de.measite.minidns; + +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.Arrays; + +import de.measite.minidns.Record.CLASS; +import de.measite.minidns.Record.TYPE; +import de.measite.minidns.util.NameUtil; + +/** + * A DNS question (request). + */ +public class Question { + + /** + * The question string (e.g. "measite.de"). + */ + private final String name; + + /** + * The question type (e.g. A). + */ + private final TYPE type; + + /** + * The question class (usually IN / internet). + */ + private final CLASS clazz; + + /** + * UnicastQueries have the highest bit of the CLASS field set to 1. + */ + private final boolean unicastQuery; + + /** + * Cache for the serialized object. + */ + 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, boolean unicastQuery) { + this.name = name; + this.type = type; + this.clazz = clazz; + this.unicastQuery = unicastQuery; + } + + /** + * 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) { + this(name, type, clazz, false); + } + + /** + * 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() { + return type; + } + + /** + * Retrieve the class of this dns question (usually internet). + * @return The class of this dns question. + */ + public CLASS getClazz() { + return clazz; + } + + /** + * Retrieve the name of this dns question (e.g. "measite.de"). + * @return The name of this dns question. + */ + public String getName() { + 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 { + String name = NameUtil.parse(dis, data); + TYPE type = TYPE.getType(dis.readUnsignedShort()); + CLASS clazz = CLASS.getClass(dis.readUnsignedShort()); + return new Question (name, type, clazz); + } + + /** + * Generate a binary paket for this dns question. + * @return The dns question. + */ + 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() | (unicastQuery ? (1 << 15) : 0)); + dos.flush(); + } catch (IOException e) { + // Should never happen + throw new IllegalStateException(e); + } + byteArray = baos.toByteArray(); + } + return byteArray; + } + + @Override + public int hashCode() { + return Arrays.hashCode(toByteArray()); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof Question)) { + return false; + } + byte t[] = toByteArray(); + byte o[] = ((Question)other).toByteArray(); + return Arrays.equals(t, o); + } + + @Override + public String toString() { + return "Question/" + clazz + "/" + type + ": " + name; + } +} |