package com.limegroup.gnutella.udpconnect;
import com.limegroup.gnutella.messages.BadPacketException;
/**
* The keepalive message is used to ensure that any firewalls continue
* to allow passage of UDP messages on the connection.
*
* Information about the senders data window for buffered incoming data
* and the highest received data packet is included in the otherwise
* unused data space within the guid. This will be required in the
* case where Ack messages stop flowing because the data window space
* has gone to zero and only KeepAliveMessages are flowing. Once the
* data window opens back up, Acks will again provide this information.
*/
public class KeepAliveMessage extends UDPConnectionMessage {
private long _windowStart;
private int _windowSpace;
/**
* Construct a new KeepAliveMessage with the specified settings and data
*/
public KeepAliveMessage(byte connectionID,
long windowStart, int windowSpace) {
super(
/* his connectionID */ connectionID,
/* opcode */ OP_KEEPALIVE,
/* Keepalive has no sequenceNumber */ 0,
/* window Start and Space */
buildByteArray((int) windowStart & 0xffff,
(windowSpace < 0 ? 0 : windowSpace)),
/* 2 short ints => 4 bytes */ 4
);
_windowStart = windowStart;
_windowSpace = windowSpace;
}
/**
* Construct a new KeepAliveMessage from the network
*/
public KeepAliveMessage(
byte[] guid, byte ttl, byte hops, byte[] payload)
throws BadPacketException {
super(guid, ttl, hops, payload);
// Parse the added windowStart and windowSpace information
_windowStart = (long)
getShortInt(guid[GUID_DATA_START],guid[GUID_DATA_START+1]);
_windowSpace =
getShortInt(guid[GUID_DATA_START+2],guid[GUID_DATA_START+3]);
}
/**
* The windowStart is equivalent to the lowest unreceived sequenceNumber
* coming from the receiving end of the connection. It is saying, I have
* received everything up to one minus this. (Note: it rolls)
*/
public long getWindowStart() {
return _windowStart;
}
/**
* Extend the windowStart of incoming messages with the full 8 bytes
* of state
*/
public void extendWindowStart(long wStart) {
_windowStart = wStart;
}
/**
* The windowSpace is a measure of how much more data the receiver can
* receive within its buffer. This number will go to zero if the
* application on the receiving side is reading data slowly. If it goes
* to zero then the sender should stop sending.
*/
public int getWindowSpace() {
return _windowSpace;
}
public String toString() {
return "KeepAliveMessage DestID:"+getConnectionID()+
" start:"+_windowStart+" space:"+_windowSpace;
}
}