package com.limegroup.gnutella.messages.vendor;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import com.limegroup.gnutella.GUID;
import com.limegroup.gnutella.messages.BadPacketException;
import com.limegroup.gnutella.messages.IPPortCombo;
/** 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 VendorMessage {
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)
throws BadPacketException {
super(guid, ttl, hops, F_LIME_VENDOR_ID, F_PUSH_PROXY_ACK, version,
payload);
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....
IPPortCombo combo =
IPPortCombo.getCombo(getPayload());
_addr = combo.getInetAddress();
_port = combo.getPort();
}
/**
* 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) {
try {
// i do it during construction....
IPPortCombo combo =
new IPPortCombo(addr.getHostAddress(), port);
return combo.toBytes();
} catch (UnknownHostException uhe) {
throw new IllegalArgumentException(uhe.getMessage());
}
}
/** Overridden purely for stats handling.
*/
protected void writePayload(OutputStream out) throws IOException {
super.writePayload(out);
}
/** Overridden purely for stats handling.
*/
public void recordDrop() {
super.recordDrop();
}
}