package com.limegroup.gnutella.messages.vendor; import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.nio.ByteOrder; import org.limewire.io.GUID; import org.limewire.io.InvalidDataException; import org.limewire.io.IpPort; import org.limewire.io.NetworkUtils; import com.limegroup.gnutella.messages.BadPacketException; /** In Vendor Message parlance, the "message type" of this VMP is "BEAR/7". * Used to ask a host you connect to do a TCP ConnectBack. */ public final class PushProxyAcknowledgement extends AbstractVendorMessage { public static final int VERSION = 2; /** The payload has 4 bytes dedicated to the IP of the proxy. */ private final InetAddress _addr; /** The payload has a 16-bit unsigned value - the port - at which one should * connect back. */ private final int _port; /** * Constructs a new PushProxyAcknowledgement message with data from the * network. */ PushProxyAcknowledgement(byte[] guid, byte ttl, byte hops, int version, byte[] payload, Network network) throws BadPacketException { super(guid, ttl, hops, F_LIME_VENDOR_ID, F_PUSH_PROXY_ACK, version, payload, network); if (getVersion() == 1) throw new BadPacketException("DEPRECATED VERSION"); if (getVersion() > VERSION) throw new BadPacketException("UNSUPPORTED VERSION"); if (getPayload().length != 6) throw new BadPacketException("UNSUPPORTED PAYLOAD LENGTH: " + payload.length); // get the ip and port from the payload.... try { IpPort combo = NetworkUtils.getIpPort(getPayload(), ByteOrder.LITTLE_ENDIAN); _addr = combo.getInetAddress(); _port = combo.getPort(); } catch(InvalidDataException ide) { throw new BadPacketException(ide); } } /** * Constructs a new PushProxyAcknowledgement message to be sent out. * @param addr The address of the person to connect back to. * @param port The port you want people to connect back to. If you give a * bad port I don't check so check yourself! */ public PushProxyAcknowledgement(InetAddress addr, int port) { super(F_LIME_VENDOR_ID, F_PUSH_PROXY_ACK, VERSION, derivePayload(addr, port)); _addr = addr; _port = port; } /** * Constructs a new PushProxyAcknowledgement message to be sent out. * @param addr The address of the person to connect back to. * @param port The port you want people to connect back to. If you give a * bad port I don't check so check yourself! * @param guid In case you want to set the guid (the PushProxy protocol * advises this). */ public PushProxyAcknowledgement(InetAddress addr, int port, GUID guid) { super(F_LIME_VENDOR_ID, F_PUSH_PROXY_ACK, VERSION, derivePayload(addr, port)); _addr = addr; _port = port; setGUID(guid); } /** @return the port the PushProxy is listening on.... */ public int getListeningPort() { return _port; } /** @return the InetAddress the PushProxy is listening on.... */ public InetAddress getListeningAddress() { return _addr; } private static byte[] derivePayload(InetAddress addr, int port) { return NetworkUtils.getBytes(addr, port, ByteOrder.LITTLE_ENDIAN); } /** Overridden purely for stats handling. */ @Override protected void writePayload(OutputStream out) throws IOException { super.writePayload(out); } }