Fixed DNS packet parsing

This commit is contained in:
Ziver Koc 2023-03-19 21:04:22 +01:00
parent d80b6a69e5
commit 2cd514df9b
3 changed files with 49 additions and 6 deletions

View file

@ -31,8 +31,9 @@ import java.io.OutputStream;
/** /**
* An Interface defining a custom field parser and writer. * An Interface defining a custom field parser and writer.
* <p> * <p>
* A new instance of the serializer will be instantiated for every time serialization is required. * One singleton instance of the serializer will be cached for the lifetime of the
* {@link BinaryStructInputStream} and {@link BinaryStructOutputStream} objects. * {@link BinaryStructInputStream} and {@link BinaryStructOutputStream} objects,
* this can be disabled by calling the {@link BinaryStructInputStream#enableSerializerCache(boolean)}.
* <p> * <p>
* NOTE: Partial octet serializing not supported. * NOTE: Partial octet serializing not supported.
*/ */

View file

@ -30,7 +30,9 @@ import zutil.io.PositionalInputStream;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* A stream class that parses a byte stream into binary struct objects. * A stream class that parses a byte stream into binary struct objects.
@ -46,9 +48,13 @@ public class BinaryStructInputStream extends InputStream{
private byte data; private byte data;
private int dataBitIndex = -1; private int dataBitIndex = -1;
private Map<Class, BinaryFieldSerializer> serializerCache;
public BinaryStructInputStream(InputStream in) { public BinaryStructInputStream(InputStream in) {
this.in = in; this.in = in;
enableSerializerCache(true);
} }
@ -78,11 +84,22 @@ public class BinaryStructInputStream extends InputStream{
*/ */
public int read(BinaryStruct struct) throws IOException { public int read(BinaryStruct struct) throws IOException {
List<BinaryFieldData> structDataList = BinaryFieldData.getStructFieldList(struct.getClass()); List<BinaryFieldData> structDataList = BinaryFieldData.getStructFieldList(struct.getClass());
PositionalInputStream positionalInputStream = new PositionalInputStream(in); PositionalInputStream positionalInputStream = (in instanceof PositionalInputStream ? (PositionalInputStream) in : new PositionalInputStream(in));
long startPos = positionalInputStream.getPosition();
for (BinaryFieldData field : structDataList) { for (BinaryFieldData field : structDataList) {
if (field.hasSerializer()) { if (field.hasSerializer()) {
BinaryFieldSerializer serializer = field.getSerializer(); // Handle serializer cache
BinaryFieldSerializer serializer = (serializerCache != null ? serializerCache.get(field.getSerializerClass()) : null);
if (serializer == null) {
serializer = field.getSerializer();
if (serializerCache != null)
serializerCache.put(serializer.getClass(), serializer);
}
// Read in field through serializer
Object value = serializer.read(positionalInputStream, field, struct); Object value = serializer.read(positionalInputStream, field, struct);
field.setValue(struct, value); field.setValue(struct, value);
@ -108,7 +125,7 @@ public class BinaryStructInputStream extends InputStream{
} }
} }
return (int) positionalInputStream.getPosition(); return (int) (positionalInputStream.getPosition() - startPos);
} }
@Override @Override
@ -150,6 +167,31 @@ public class BinaryStructInputStream extends InputStream{
} }
/**
* Enable or disable the caching of serializer objects. If disabled then
* a new instance of the serializer will be created every time it is needed.
* <p>
* By default, caching is enabled.
*
* @param enabled set true to enable caching or false to disable.
*/
public void enableSerializerCache(boolean enabled) {
if (enabled) {
serializerCache = new HashMap<>();
} else {
serializerCache = null;
}
}
/**
* Method will clear all cached instances of serializer objects.
*/
public void clearSerializerCache() {
if (serializerCache != null) {
serializerCache.clear();
}
}
protected static int shiftLeftBy(int bitIndex, int bitLength) { protected static int shiftLeftBy(int bitIndex, int bitLength) {
return (8 - ((7-bitIndex) + bitLength) % 8) % 8; return (8 - ((7-bitIndex) + bitLength) % 8) % 8;
} }

View file

@ -437,7 +437,7 @@ Multicast Domain Name System (query)
DnsPacketQuestion question2 = packet.getQuestions().get(1); DnsPacketQuestion question2 = packet.getQuestions().get(1);
assertEquals("qNAME", "_homekit._tcp.local", question2.name); assertEquals("qNAME", "_homekit._tcp.local", question2.name);
//assertEquals("qNAME", "_homekit.<28>", question2.name); // TODO: Fix support for string pointers //assertEquals("qNAME", "_homekit.<28>", question2.name);
assertEquals("type", DnsConstants.TYPE.PTR, question2.type); assertEquals("type", DnsConstants.TYPE.PTR, question2.type);
assertEquals("clazz", DnsConstants.CLASS.IN, question2.clazz); assertEquals("clazz", DnsConstants.CLASS.IN, question2.clazz);