/* * This file is part of mlDHT. * * mlDHT is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * mlDHT is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with mlDHT. If not, see <http://www.gnu.org/licenses/>. */ package lbms.plugins.mldht.kad.utils; import java.net.Inet4Address; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.nio.ByteBuffer; import lbms.plugins.mldht.kad.DHT.DHTtype; import lbms.plugins.mldht.kad.KBucketEntry; import lbms.plugins.mldht.kad.Key; /** * @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), Short.toUnsignedInt(bb.getShort())); } catch (UnknownHostException e) { e.printStackTrace(); throw new RuntimeException(e); } return new KBucketEntry(addr, new Key(key), 0); } }