Package net.i2p.client.streaming.impl
Class Packet
- java.lang.Object
-
- net.i2p.client.streaming.impl.Packet
-
- Direct Known Subclasses:
PacketLocal
class Packet extends Object
This contains solely the data that goes out on the wire, including the local and remote port which is embedded in the I2CP overhead, not in the packet itself. This is the class used for inbound packets. For local state saved for outbound packets, see the PacketLocal extension.Contain a single packet transferred as part of a streaming connection. The data format is as follows:
sendStreamId
[4 byte value]receiveStreamId
[4 byte value]sequenceNum
[4 byte unsigned integer]ackThrough
[4 byte unsigned integer]- number of NACKs [1 byte unsigned integer]
- that many
NACKs
resendDelay
[1 byte integer]- flags [2 byte value]
- option data size [2 byte integer]
- option data specified by those flags [0 or more bytes]
- payload [remaining packet size]
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):
FLAG_SYNCHRONIZE
: no option dataFLAG_CLOSE
: no option dataFLAG_RESET
: no option dataFLAG_SIGNATURE_INCLUDED
:Signature
FLAG_SIGNATURE_REQUESTED
: no option dataFLAG_FROM_INCLUDED
:Destination
FLAG_DELAY_REQUESTED
: 2 byte integerFLAG_MAX_PACKET_SIZE_INCLUDED
: 2 byte integerFLAG_PROFILE_INTERACTIVE
: no option dataFLAG_ECHO
: no option dataFLAG_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
NOTE: All setters unsynchronized.
-
-
Field Summary
Fields Modifier and Type Field Description protected long[]
_nacks
protected Signature
_offlineSignature
protected Destination
_optionFrom
protected Signature
_optionSignature
protected I2PSession
_session
protected long
_transientExpires
protected SigningPublicKey
_transientSigningPublicKey
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 anythingstatic 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_OFFLINE
If set, an offline signing block is in the options.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 int
MIN_DELAY_CHOKE
static int
SEND_DELAY_CHOKE
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
Constructors Constructor Description Packet(I2PSession session)
Does no initialization.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description ByteArray
acquirePayload()
protected StringBuilder
formatAsString()
long
getAckThrough()
The highest packet sequence number that received on the receiveStreamId.int
getLocalPort()
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) Warning, may be typed wrong on incoming packets for EdDSA before verifySignature() is called.ByteArray
getPayload()
get the actual payload of the message.int
getPayloadSize()
long
getReceiveStreamId()
stream the replies should be sent on.int
getRemotePort()
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 sendStreamI2PSession
getSession()
SigningPublicKey
getTransientSPK()
Only if an offline signing block was included, else nullboolean
isFlagSet(int flag)
is a particular flag set on this packet?void
logTCPDump(Connection con)
Generate a pcap/tcpdump-compatible format, so we can use standard debugging tools.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()
does nothing right nowvoid
setAckThrough(long id)
void
setFlag(int flag)
void
setFlag(int flag, boolean set)
void
setLocalPort(int port)
Must be called to change the port, not set by readPacket() as the port is out-of-band in the I2CP header.void
setNacks(long[] nacks)
void
setOptionalDelay(int delayMs)
Caller must also call setFlag(FLAG_DELAY_REQUESTED)void
setOptionalMaxSize(int numBytes)
This also sets flag FLAG_MAX_PACKET_SIZE_INCLUDEDvoid
setOptionalSignature(Signature sig)
This also sets flag FLAG_SIGNATURE_INCLUDEDvoid
setPayload(ByteArray payload)
void
setReceiveStreamId(long id)
void
setRemotePort(int port)
Must be called to change the port, not set by readPacket() as the port is out-of-band in the I2CP header.void
setResendDelay(int numSeconds)
Unused.void
setSendStreamId(long id)
void
setSequenceNum(long num)
(package private) static String
toId(long id)
String
toString()
boolean
verifySignature(I2PAppContext ctx, byte[] buffer)
Determine whether the signature on the data is valid.boolean
verifySignature(I2PAppContext ctx, SigningPublicKey altSPK, 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.protected int
writePacket(byte[] buffer, int offset, int fakeSigLen)
-
-
-
Field Detail
-
_session
protected final I2PSession _session
-
_nacks
protected long[] _nacks
-
_optionSignature
protected Signature _optionSignature
-
_optionFrom
protected Destination _optionFrom
-
_transientExpires
protected long _transientExpires
-
_offlineSignature
protected Signature _offlineSignature
-
_transientSigningPublicKey
protected SigningPublicKey _transientSigningPublicKey
-
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
-
FLAG_SIGNATURE_OFFLINE
public static final int FLAG_SIGNATURE_OFFLINE
If set, an offline signing block is in the options.- Since:
- 0.9.39
- 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
-
MIN_DELAY_CHOKE
public static final int MIN_DELAY_CHOKE
- See Also:
- Constant Field Values
-
SEND_DELAY_CHOKE
public static final int SEND_DELAY_CHOKE
- 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(I2PSession session)
Does no initialization. See readPacket() for inbound packets, and the setters for outbound packets.
-
-
Method Detail
-
getSession
public I2PSession getSession()
- Since:
- 0.9.21
-
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, or -1 if FLAG_NO_ACK
-
setAckThrough
public void setAckThrough(long id)
- Parameters:
id
- if < 0, sets FLAG_NO_ACK
-
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()
does nothing right now
-
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)
- Parameters:
flag
- bitmask of any flag(s)
-
setFlag
public void setFlag(int flag, boolean set)
- Parameters:
flag
- bitmask of any flag(s)set
- true to set, false to clear
-
getOptionalSignature
public Signature getOptionalSignature()
The signature on the packet (only included if the flag for it is set) Warning, may be typed wrong on incoming packets for EdDSA before verifySignature() is called.- Returns:
- signature on the packet if the flag for signatures is set
-
setOptionalSignature
public void setOptionalSignature(Signature sig)
This also sets flag FLAG_SIGNATURE_INCLUDED
-
getOptionalFrom
public Destination getOptionalFrom()
the sender of the packet (only included if the flag for it is set)- Returns:
- the sending Destination
-
getTransientSPK
public SigningPublicKey getTransientSPK()
Only if an offline signing block was included, else null- Since:
- 0.9.39
-
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)
Caller must also call setFlag(FLAG_DELAY_REQUESTED)
-
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) or zero if unset
-
setOptionalMaxSize
public void setOptionalMaxSize(int numBytes)
This also sets flag FLAG_MAX_PACKET_SIZE_INCLUDED
-
getLocalPort
public int getLocalPort()
- Returns:
- Default I2PSession.PORT_UNSPECIFIED (0) or PORT_ANY (0)
- Since:
- 0.8.9
-
setLocalPort
public void setLocalPort(int port)
Must be called to change the port, not set by readPacket() as the port is out-of-band in the I2CP header.- Since:
- 0.8.9
-
getRemotePort
public int getRemotePort()
- Returns:
- Default I2PSession.PORT_UNSPECIFIED (0) or PORT_ANY (0)
- Since:
- 0.8.9
-
setRemotePort
public void setRemotePort(int port)
Must be called to change the port, not set by readPacket() as the port is out-of-band in the I2CP header.- Since:
- 0.8.9
-
writePacket
public int writePacket(byte[] buffer, int offset) throws 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 destinationoffset
- starting point in the buffer to send- Returns:
- Count actually written
- Throws:
IllegalStateException
- if there is data missing or otherwise b0rked
-
writePacket
protected int writePacket(byte[] buffer, int offset, int fakeSigLen) throws IllegalStateException
- Parameters:
fakeSigLen
- if 0, include the real signature in _optionSignature; if nonzero, leave space for that many bytes- Throws:
IllegalStateException
-
readPacket
public void readPacket(byte[] buffer, int offset, int length) throws IllegalArgumentException
Read the packet from the buffer (starting at the offset) and return the number of bytes read.- Parameters:
buffer
- packet buffer containing the dataoffset
- index into the buffer to start readignlength
- how many bytes within the buffer past the offset are part of the packet?- Throws:
IllegalArgumentException
- if the data is b0rkedIndexOutOfBoundsException
- if the data is b0rked
-
verifySignature
public boolean verifySignature(I2PAppContext ctx, byte[] buffer)
Determine whether the signature on the data is valid. Packet MUST have a FROM option or will return false.- Parameters:
ctx
- Application contextbuffer
- data to validate with signature, or null to use our own buffer.- Returns:
- true if the signature exists and validates against the data, false otherwise.
- Since:
- 0.9.39
-
verifySignature
public boolean verifySignature(I2PAppContext ctx, SigningPublicKey altSPK, byte[] buffer)
Determine whether the signature on the data is valid.- Parameters:
ctx
- Application contextaltSPK
- Signing key to verify with, ONLY if there is no FROM field in this packet. May be the SPK from a FROM field or offline sig field from a previous packet on this connection. Ignored if this packet contains a FROM option block. Null ok if none available.buffer
- data to validate with signature, or null to use our own buffer.- Returns:
- true if the signature exists and validates against the data, false otherwise.
-
formatAsString
protected StringBuilder formatAsString()
-
toId
static final String toId(long id)
-
logTCPDump
public void logTCPDump(Connection con)
Generate a pcap/tcpdump-compatible format, so we can use standard debugging tools.
-
-