net.i2p.client.streaming
Class Packet

java.lang.Object
  extended by net.i2p.client.streaming.Packet
Direct Known Subclasses:
PacketLocal

public class Packet
extends java.lang.Object

Contain a single packet transferred as part of a streaming connection. The data format is as follows:

The flags field above specifies some metadata about the packet, and in turn may require certain additional data to be included. The flags are as follows (with any data structures specified added to the options area in the given order):

  1. FLAG_SYNCHRONIZE: no option data
  2. FLAG_CLOSE: no option data
  3. FLAG_RESET: no option data
  4. FLAG_SIGNATURE_INCLUDED: Signature
  5. FLAG_SIGNATURE_REQUESTED: no option data
  6. FLAG_FROM_INCLUDED: Destination
  7. FLAG_DELAY_REQUESTED: 2 byte integer
  8. FLAG_MAX_PACKET_SIZE_INCLUDED: 2 byte integer
  9. FLAG_PROFILE_INTERACTIVE: no option data
  10. FLAG_ECHO: no option data
  11. FLAG_NO_ACK: no option data - this appears to be unused, we always ack, even for the first packet

If the signature is included, it uses the Destination's DSA key to sign the entire header and payload with the space in the options for the signature being set to all zeroes.

If the sequenceNum is 0 and the SYN is not set, this is a plain ACK packet that should not be ACKed


Field Summary
static int DEFAULT_MAX_SIZE
           
static int FLAG_CLOSE
          The sender of this packet will not be sending any more payload data.
static int FLAG_DELAY_REQUESTED
          This packet includes an explicit request for the recipient to delay sending any packets with data for a given amount of time.
static int FLAG_ECHO
          If set, this packet is a ping (if sendStreamId is set) or a ping reply (if receiveStreamId is set).
static int FLAG_FROM_INCLUDED
          This packet includes the full I2P destination of the packet's sender.
static int FLAG_MAX_PACKET_SIZE_INCLUDED
          This packet includes a request that the recipient not send any subsequent packets with payloads greater than a specific size.
static int FLAG_NO_ACK
          If set, this packet doesn't really want to ack anything
static int FLAG_PROFILE_INTERACTIVE
          If set, this packet is travelling as part of an interactive flow, meaning it is more lag sensitive than throughput sensitive.
static int FLAG_RESET
          This packet is being sent to signify that the socket does not exist (or, if in response to an initial synchronize packet, that the connection was refused).
static int FLAG_SIGNATURE_INCLUDED
          This packet contains a DSA signature from the packet's sender.
static int FLAG_SIGNATURE_REQUESTED
          This packet wants the recipient to include signatures on subsequent packets sent to the creator of this packet.
static int FLAG_SYNCHRONIZE
          This packet is creating a new socket connection (if the receiveStreamId is STREAM_ID_UNKNOWN) or it is acknowledging a request to create a connection and in turn is accepting the socket.
protected static int MAX_DELAY_REQUEST
           
static int MAX_PAYLOAD_SIZE
           
static long MAX_STREAM_ID
           
static long STREAM_ID_UNKNOWN
          The receiveStreamId will be set to this when the packet doesn't know what ID will be assigned by the remote peer (aka this is the initial synchronize packet)
 
Constructor Summary
Packet()
           
 
Method Summary
 ByteArray acquirePayload()
           
protected  java.lang.StringBuilder formatAsString()
           
 long getAckThrough()
          The highest packet sequence number that received on the receiveStreamId.
 long[] getNacks()
          List of packet sequence numbers below the getAckThrough() value have not been received.
 int getOptionalDelay()
          How many milliseconds the sender of this packet wants the recipient to wait before sending any more data (only valid if the flag for it is set)
 Destination getOptionalFrom()
          the sender of the packet (only included if the flag for it is set)
 int getOptionalMaxSize()
          What is the largest payload the sender of this packet wants to receive?
 Signature getOptionalSignature()
          the signature on the packet (only included if the flag for it is set)
 ByteArray getPayload()
          get the actual payload of the message.
 int getPayloadSize()
           
 long getReceiveStreamId()
          stream the replies should be sent on.
 int getResendDelay()
          How long is the creator of this packet going to wait before resending this packet (if it hasn't yet been ACKed).
 long getSendStreamId()
          what stream do we send data to the peer on?
 long getSequenceNum()
          0-indexed sequence number for this Packet in the sendStream
 boolean isFlagSet(int flag)
          is a particular flag set on this packet?
 void readPacket(byte[] buffer, int offset, int length)
          Read the packet from the buffer (starting at the offset) and return the number of bytes read.
 void releasePayload()
           
 void setAckThrough(long id)
           
 void setFlag(int flag)
           
 void setFlag(int flag, boolean set)
           
 void setFlags(int flags)
           
 void setNacks(long[] nacks)
           
 void setOptionalDelay(int delayMs)
           
 void setOptionalFrom(Destination from)
           
 void setOptionalMaxSize(int numBytes)
           
 void setOptionalSignature(Signature sig)
           
 void setPayload(ByteArray payload)
           
 void setReceiveStreamId(long id)
           
 void setResendDelay(int numSeconds)
          Unused.
 void setSendStreamId(long id)
           
 void setSequenceNum(long num)
           
(package private) static java.lang.String toId(long id)
           
 java.lang.String toString()
           
 boolean verifySignature(I2PAppContext ctx, Destination from, byte[] buffer)
          Determine whether the signature on the data is valid.
 int writePacket(byte[] buffer, int offset)
          Write the packet to the buffer (starting at the offset) and return the number of bytes written.
 int writeSignedPacket(byte[] buffer, int offset, I2PAppContext ctx, SigningPrivateKey key)
          Sign and write the packet to the buffer (starting at the offset) and return the number of bytes written.
 int writtenSize()
          how large would this packet be if we wrote it
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

STREAM_ID_UNKNOWN

public static final long STREAM_ID_UNKNOWN
The receiveStreamId will be set to this when the packet doesn't know what ID will be assigned by the remote peer (aka this is the initial synchronize packet)

See Also:
Constant Field Values

MAX_STREAM_ID

public static final long MAX_STREAM_ID
See Also:
Constant Field Values

FLAG_SYNCHRONIZE

public static final int FLAG_SYNCHRONIZE
This packet is creating a new socket connection (if the receiveStreamId is STREAM_ID_UNKNOWN) or it is acknowledging a request to create a connection and in turn is accepting the socket.

See Also:
Constant Field Values

FLAG_CLOSE

public static final int FLAG_CLOSE
The sender of this packet will not be sending any more payload data.

See Also:
Constant Field Values

FLAG_RESET

public static final int FLAG_RESET
This packet is being sent to signify that the socket does not exist (or, if in response to an initial synchronize packet, that the connection was refused).

See Also:
Constant Field Values

FLAG_SIGNATURE_INCLUDED

public static final int FLAG_SIGNATURE_INCLUDED
This packet contains a DSA signature from the packet's sender. This signature is within the packet options. All synchronize packets must have this flag set.

See Also:
Constant Field Values

FLAG_SIGNATURE_REQUESTED

public static final int FLAG_SIGNATURE_REQUESTED
This packet wants the recipient to include signatures on subsequent packets sent to the creator of this packet.

See Also:
Constant Field Values

FLAG_FROM_INCLUDED

public static final int FLAG_FROM_INCLUDED
This packet includes the full I2P destination of the packet's sender. The initial synchronize packet must have this flag set.

See Also:
Constant Field Values

FLAG_DELAY_REQUESTED

public static final int FLAG_DELAY_REQUESTED
This packet includes an explicit request for the recipient to delay sending any packets with data for a given amount of time.

See Also:
Constant Field Values

FLAG_MAX_PACKET_SIZE_INCLUDED

public static final int FLAG_MAX_PACKET_SIZE_INCLUDED
This packet includes a request that the recipient not send any subsequent packets with payloads greater than a specific size. If not set and no prior value was delivered, the maximum value will be assumed (approximately 32KB).

See Also:
Constant Field Values

FLAG_PROFILE_INTERACTIVE

public static final int FLAG_PROFILE_INTERACTIVE
If set, this packet is travelling as part of an interactive flow, meaning it is more lag sensitive than throughput sensitive. aka send data ASAP rather than waiting around to send full packets.

See Also:
Constant Field Values

FLAG_ECHO

public static final int FLAG_ECHO
If set, this packet is a ping (if sendStreamId is set) or a ping reply (if receiveStreamId is set).

See Also:
Constant Field Values

FLAG_NO_ACK

public static final int FLAG_NO_ACK
If set, this packet doesn't really want to ack anything

See Also:
Constant Field Values

DEFAULT_MAX_SIZE

public static final int DEFAULT_MAX_SIZE
See Also:
Constant Field Values

MAX_DELAY_REQUEST

protected static final int MAX_DELAY_REQUEST
See Also:
Constant Field Values

MAX_PAYLOAD_SIZE

public static final int MAX_PAYLOAD_SIZE
See Also:
Constant Field Values
Constructor Detail

Packet

public Packet()
Method Detail

getSendStreamId

public long getSendStreamId()
what stream do we send data to the peer on?

Returns:
stream ID we use to send data

setSendStreamId

public void setSendStreamId(long id)

getReceiveStreamId

public long getReceiveStreamId()
stream the replies should be sent on. this should be 0 if the connection is still being built.

Returns:
stream ID we use to get data, zero if the connection is still being built.

setReceiveStreamId

public void setReceiveStreamId(long id)

getSequenceNum

public long getSequenceNum()
0-indexed sequence number for this Packet in the sendStream

Returns:
0-indexed sequence number for current Packet in current sendStream

setSequenceNum

public void setSequenceNum(long num)

getAckThrough

public long getAckThrough()
The highest packet sequence number that received on the receiveStreamId. This field is ignored on the initial connection packet (where receiveStreamId is the unknown id) or if FLAG_NO_ACK is set.

Returns:
The highest packet sequence number received on receiveStreamId

setAckThrough

public void setAckThrough(long id)

getNacks

public long[] getNacks()
List of packet sequence numbers below the getAckThrough() value have not been received. this may be null.

Returns:
List of packet sequence numbers not ACKed, or null if there are none.

setNacks

public void setNacks(long[] nacks)

getResendDelay

public int getResendDelay()
How long is the creator of this packet going to wait before resending this packet (if it hasn't yet been ACKed). The value is seconds since the packet was created. Unused. Broken before release 0.7.8 Not to be used without sanitizing for huge values. Setters from options did not divide by 1000, and the options default is 1000, so the value sent in the 1-byte field was always 1000 & 0xff = 0xe8 = 232

Returns:
Delay before resending a packet in seconds.

setResendDelay

public void setResendDelay(int numSeconds)
Unused. Broken before release 0.7.8 See above


getPayload

public ByteArray getPayload()
get the actual payload of the message. may be null

Returns:
the payload of the message, null if none.

setPayload

public void setPayload(ByteArray payload)

getPayloadSize

public int getPayloadSize()

releasePayload

public void releasePayload()

acquirePayload

public ByteArray acquirePayload()

isFlagSet

public boolean isFlagSet(int flag)
is a particular flag set on this packet?

Parameters:
flag - bitmask of any flag(s)
Returns:
true if set, false if not.

setFlag

public void setFlag(int flag)

setFlag

public void setFlag(int flag,
                    boolean set)

setFlags

public void setFlags(int flags)

getOptionalSignature

public Signature getOptionalSignature()
the signature on the packet (only included if the flag for it is set)

Returns:
signature on the packet if the flag for signatures is set

setOptionalSignature

public void setOptionalSignature(Signature sig)

getOptionalFrom

public Destination getOptionalFrom()
the sender of the packet (only included if the flag for it is set)

Returns:
the sending Destination

setOptionalFrom

public void setOptionalFrom(Destination from)

getOptionalDelay

public int getOptionalDelay()
How many milliseconds the sender of this packet wants the recipient to wait before sending any more data (only valid if the flag for it is set)

Returns:
How long the sender wants the recipient to wait before sending any more data in ms.

setOptionalDelay

public void setOptionalDelay(int delayMs)

getOptionalMaxSize

public int getOptionalMaxSize()
What is the largest payload the sender of this packet wants to receive?

Returns:
Maximum payload size sender can receive (MRU)

setOptionalMaxSize

public void setOptionalMaxSize(int numBytes)

writePacket

public int writePacket(byte[] buffer,
                       int offset)
                throws java.lang.IllegalStateException
Write the packet to the buffer (starting at the offset) and return the number of bytes written.

Parameters:
buffer - bytes to write to a destination
offset - starting point in the buffer to send
Returns:
Count actually written
Throws:
java.lang.IllegalStateException - if there is data missing or otherwise b0rked

writtenSize

public int writtenSize()
                throws java.lang.IllegalStateException
how large would this packet be if we wrote it

Returns:
How large the current packet would be
Throws:
java.lang.IllegalStateException

readPacket

public void readPacket(byte[] buffer,
                       int offset,
                       int length)
                throws java.lang.IllegalArgumentException
Read the packet from the buffer (starting at the offset) and return the number of bytes read.

Parameters:
buffer - packet buffer containing the data
offset - index into the buffer to start readign
length - how many bytes within the buffer past the offset are part of the packet?
Throws:
java.lang.IllegalArgumentException - if the data is b0rked

verifySignature

public boolean verifySignature(I2PAppContext ctx,
                               Destination from,
                               byte[] buffer)
Determine whether the signature on the data is valid.

Parameters:
ctx - Application context
from - the Destination the data came from
buffer - data to validate with signature
Returns:
true if the signature exists and validates against the data, false otherwise.

writeSignedPacket

public int writeSignedPacket(byte[] buffer,
                             int offset,
                             I2PAppContext ctx,
                             SigningPrivateKey key)
                      throws java.lang.IllegalStateException
Sign and write the packet to the buffer (starting at the offset) and return the number of bytes written.

Parameters:
buffer - data to be written
offset - starting point in the buffer
ctx - Application Context
key - signing key
Returns:
Count of bytes written
Throws:
java.lang.IllegalStateException - if there is data missing or otherwise b0rked

toString

public java.lang.String toString()
Overrides:
toString in class java.lang.Object

formatAsString

protected java.lang.StringBuilder formatAsString()

toId

static final java.lang.String toId(long id)