package lbms.plugins.mldht.kad;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.List;
import lbms.plugins.mldht.kad.DHT.DHTtype;
/**
* @author Damokles
*
*/
public class PackUtil {
/**
* Packs a BucketEntry into the provided buffer.
*
* @param e Entry to insert
* @param buffer must be at least 26bytes per Entry
* @param off Offset to use
* @throws IllegalArgumentException if buffer is too small
*/
public static void PackBucketEntry (KBucketEntry e, byte[] buffer, int off, DHTtype type) {
// first check size
if (off + type.NODES_ENTRY_LENGTH > buffer.length) {
throw new IllegalArgumentException("Not enough room in buffer");
}
ByteBuffer bb = ByteBuffer.wrap(buffer, off, type.NODES_ENTRY_LENGTH);
InetSocketAddress addr = e.getAddress();
if(type == DHTtype.IPV6_DHT && addr.getAddress() instanceof Inet4Address)
throw new IllegalArgumentException("Attempting to serialize an IPv4 bucket entry into nodes6 buffer");
// copy ID, IP address and port into the buffer
bb.put(e.getID().getHash());
bb.put(addr.getAddress().getAddress());
//bt::WriteUint32(ptr,20,addr.ipAddress().IPv4Addr());
bb.putShort((short) addr.getPort());
}
/**
* Unpacks a Entry from a byte array
*
* @param buffer byte array with serialized entry
* @param off the Offset to use
* @return deserialized Entry
* @throws IllegalArgumentException if buffer is to small
*/
public static KBucketEntry UnpackBucketEntry (byte[] buffer, int off, DHTtype type) {
if (off + type.NODES_ENTRY_LENGTH > buffer.length) {
throw new IllegalArgumentException("Not enough room in buffer");
}
ByteBuffer bb = ByteBuffer.wrap(buffer, off, type.NODES_ENTRY_LENGTH);
byte[] key = new byte[20];
bb.get(key);
byte[] inetaddr = new byte[type.NODES_ENTRY_LENGTH - 20 - 2];
bb.get(inetaddr);
InetSocketAddress addr = null;
//UnknownHostException shouldn't occur since IP is provided
try {
addr = new InetSocketAddress(InetAddress.getByAddress(inetaddr),
bb.getShort() & 0xFFFF); // & 0xFFFF is used to get an unsigned short
} catch (UnknownHostException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return new KBucketEntry(addr, new Key(key), 0);
}
}