package org.torrent.internal.peer; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; import org.torrent.internal.bencoding.BMap; import org.torrent.internal.bencoding.BTypeException; import org.torrent.internal.data.Hash; import org.torrent.internal.data.InetSocketAddress; import org.torrent.internal.util.Validator; public class PeerInfo { private static final String PEER_ID = "peer id"; private static final String IP = "ip"; private static final String PORT = "port"; private final InetSocketAddress address; private final Hash peerID; public static PeerInfo fromAddress(Hash peerID, InetSocketAddress addr) { return getPeerInfo(peerID, addr); } public static PeerInfo fromBMap(BMap peer) throws BTypeException { Validator.notNull(peer, "Peer map is null!"); return getPeerInfo( new Hash((byte[]) peer.get(PEER_ID), Hash.Type.ID), new InetSocketAddress(peer.getString(IP), peer.getInteger(PORT))); } private PeerInfo(Hash peerID, InetSocketAddress addr) { Validator.notNull(addr, "Address is null!"); this.peerID = peerID; this.address = addr; } public static PeerInfo fromRawIP(byte[] array, int off, int len) { Validator.notNull(array, "Array is null!"); Validator.isTrue(off >= 0 && off + len <= array.length, "Out of bounds: off=" + off + " len=" + len + " array.length=" + array.length); try { return getPeerInfo(null, new InetSocketAddress( InetAddress.getByAddress( Arrays.copyOfRange(array, off, off + len - 2)) .getHostAddress(), ((array[off + len - 2] & 0xff) << 8) | (array[off + len - 1] & 0xff))); } catch (UnknownHostException e) { throw new RuntimeException(e); } } public InetSocketAddress getAddress() { return address; } /** * Returns the ID of the peer if available. * * @return */ public Hash getPeerID() { return peerID; } @Override public int hashCode() { return address.hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof PeerInfo) { PeerInfo other = (PeerInfo) obj; if (peerID != null && !peerID.equals(other.peerID)) { return false; } return address.equals(other.address); } return false; } @Override public String toString() { return "[Peer: " + peerID + ", address: " + address + "]"; } /** * Helper method (maybe doing flyweight pattern later on) */ private static PeerInfo getPeerInfo(Hash peerID, InetSocketAddress addr) { return new PeerInfo(peerID, addr); } }