java.lang.Object
net.i2p.router.transport.udp.OutboundMessageState
Field Summary
Modifier and TypeFieldDescriptionprivate intHow many bytespush(List)is allowed to send.private final I2PAppContextThe app context.private longWhen the message was last enqueued, tracked here since the message itself is null for injections.private final longWhen the message expires.private longTime of first fragment send (for network RTT measurement, excludes queue time).private longBitmask, 0 if acked, all 0 = complete.private final byte[]Sends for each fragment, or null if only one fragment.private final intFixed fragment size across the message.private final I2NPMessageThe message being tracked.private final LogLogger for the outbound message state.private intMost sends of the message allowed.private final OutNetMessageMay be null if we are part of the establishment.private final byte[]The message bytes prepared for sending.private static longConfigurable message expiration.private final AtomicIntegerNacks received for the fragments.private final intFragments the message was split into.private final PeerStateWill be null, unless we are part of the establishment.private intTimes the message has been pushed.private longSequence number of the message.private final longWhen the message sending started.static final intLargest message body SSU will carry, in bytes; larger ones are rejected.Constructor Summary
ModifierConstructorDescriptionOutboundMessageState(I2PAppContext context, I2NPMessage msg, PeerState peer) "injected" message from the establisher.privateOutboundMessageState(I2PAppContext context, OutNetMessage m, I2NPMessage msg, PeerState peer) Fragments the given message for transmission.OutboundMessageState(I2PAppContext context, OutNetMessage m, PeerState peer) Normal constructor.Method Summary
Modifier and TypeMethodDescriptionbooleanacked(int fragmentNum) Ack this fragment number.booleanacked(ACKBitfield bitfield) Ack all the fragments in the ack list.voidReset the NACK counter to zero, so the retransmission accounting for this message starts over from the next ACK.voiddrop()For CDQ.intfragmentSize(int fragmentNum) The size in bytes of the fragment.longFor CDQ.intHow many fragments in the message.longThe lifetime.intThe max number of sends for any fragment.The message.static longHow long an outbound SSU message stays in flight before it is dropped.longThe message ID.intThe size of the I2NP message.private intThe min send count of unacked fragments.intThe minimum number of bytes we can send, which is the smallest unacked fragment we will send next.intgetNACKs()The NACK count.getPeer()The peer.intFor CDPQ.intThe number of times we've pushed some fragments.longNetwork RTT: time since first fragment was sent (excludes queue time).intgetSendSize(int max) How many bytes we can send under the max given.longFor CDPQ.longWhen this message was created, for computing lifetime without a repeated clock read in hot loops.intHow many fragments of the message still need an ack.intThe total size of the fragments that have not yet been acked, counting the packet overhead of each fragment needing to be sent.intThe SSU 2 version of the peer.booleanIs any fragment unsent?intIncrement and return the NACK count.booleanWhether all fragments have been acked.booleanWhether the message has expired.booleanisExpired(long now) Whether the message has expired at the given time.private static longmask(int fragment) Bit mask for the given fragment index.booleanneedsSending(int fragment) Whether the fragment has not been ACKed.intpush(List<PacketBuilder2.Fragment> toSend) Add fragments up to the number of bytes allowed by setAllowedSendBytes() Side effects: Clears setAllowedSendBytes.voidsetEnqueueTime(long now) For CDQ.static voidsetMessageExpiration(long ms) The outbound message expiration, called by Tuner.voidsetSeqNum(long num) For CDPQ.toString()A string summary of this message state.intwriteFragment(byte[] out, int outOffset, int fragmentNum) Write a part of the the message onto the specified buffer.
Field Details
_context
The app context._log
Logger for the outbound message state._message
May be null if we are part of the establishment._i2npMessage
The message being tracked._peer
Will be null, unless we are part of the establishment._expiration
private final long _expirationWhen the message expires._messageBuf
private final byte[] _messageBufThe message bytes prepared for sending._fragmentSize
private final int _fragmentSizeFixed fragment size across the message._fragmentAcks
private long _fragmentAcksBitmask, 0 if acked, all 0 = complete._numFragments
private final int _numFragmentsFragments the message was split into._fragmentSends
private final byte[] _fragmentSendsSends for each fragment, or null if only one fragment._startedOn
private final long _startedOnWhen the message sending started._firstSendTime
private volatile long _firstSendTimeTime of first fragment send (for network RTT measurement, excludes queue time)._pushCount
private int _pushCountTimes the message has been pushed._maxSends
private int _maxSendsMost sends of the message allowed._enqueueTime
private volatile long _enqueueTimeWhen the message was last enqueued, tracked here since the message itself is null for injections._seqNum
private volatile long _seqNumSequence number of the message._allowedSendBytes
private int _allowedSendBytesHow many bytespush(List)is allowed to send._nacks
Nacks received for the fragments.MAX_MSG_SIZE
public static final int MAX_MSG_SIZELargest message body SSU will carry, in bytes; larger ones are rejected.- See Also:
_messageExpiration
private static volatile long _messageExpirationConfigurable message expiration. Default 60s, adjusted by Tuner under load.
Constructor Details
OutboundMessageState
"injected" message from the establisher.Called from
UDPTransport.- Parameters:
context- the router context supplying the clock and bandwidth managermsg- the message to fragment and sendpeer- the peer the message is destined for- Throws:
IllegalArgumentException- if too big or if msg or peer is null
OutboundMessageState
Normal constructor.Called from
OutboundMessageFragments.- Parameters:
context- the router context supplying the clock and bandwidth managerm- the outbound message carrying the payload and its send optionspeer- the peer the message is destined for- Throws:
IllegalArgumentException- if too big or if msg or peer is null
OutboundMessageState
private OutboundMessageState(I2PAppContext context, OutNetMessage m, I2NPMessage msg, PeerState peer) Fragments the given message for transmission.- Parameters:
context- the application contextm- null if msg is "injected"msg- the message to fragmentpeer- the peer the message is being sent to- Throws:
IllegalArgumentException- if too big or if msg or peer is null
Method Details
getMessageExpiration
public static long getMessageExpiration()How long an outbound SSU message stays in flight before it is dropped.- Returns:
- the duration in ms, 5000-300000, 60000 unless the Tuner changed it
setMessageExpiration
public static void setMessageExpiration(long ms) The outbound message expiration, called by Tuner.- Parameters:
ms- expiration in ms, clamped to [5000, 300000]
getVersion
public int getVersion()The SSU 2 version of the peer.- Returns:
- the peer's SSU version, 1 for SSU1
mask
private static long mask(int fragment) Bit mask for the given fragment index.- Parameters:
fragment- 0-63- Returns:
- a long with bit
fragmentset
getMessage
getMessageId
public long getMessageId()The message ID.- Returns:
- the unique ID of the I2NP message being tracked
incrementNACKs
public int incrementNACKs()Increment and return the NACK count.- Returns:
- new value
getNACKs
public int getNACKs()The NACK count.- Returns:
- the nacks received since the last ACK
clearNACKs
public void clearNACKs()Reset the NACK counter to zero, so the retransmission accounting for this message starts over from the next ACK.getPeer
isExpired
public boolean isExpired()Whether the message has expired.- Returns:
- true if the expiration is before the current time
isExpired
public boolean isExpired(long now) Whether the message has expired at the given time.- Parameters:
now- the current time in milliseconds since the epoch to test against- Returns:
- true if the expiration is before the given time
isComplete
public boolean isComplete()Whether all fragments have been acked.- Returns:
- true when the ack bitmask has no bits left set
getUnackedSize
public int getUnackedSize()The total size of the fragments that have not yet been acked, counting the packet overhead of each fragment needing to be sent.- Returns:
- the unacked size
getUnackedFragments
public int getUnackedFragments()How many fragments of the message still need an ack.- Returns:
- 0 when the message is complete, otherwise 1 to the fragment count
hasUnsentFragments
public boolean hasUnsentFragments()Is any fragment unsent?- Returns:
- whether unsent fragments is present
getMinSendCount
private int getMinSendCount()The min send count of unacked fragments. Only call if not complete and _numFragments greater than 1. Caller must synch.- Returns:
- the min send count
getMinSendSize
public int getMinSendSize()The minimum number of bytes we can send, which is the smallest unacked fragment we will send next. Includes packet overhead.- Returns:
- 0 to total size
getSendSize
public int getSendSize(int max) How many bytes we can send under the max given. Side effect: if applicable, amount to send will be saved for the push() call. Note: With multiple fragments, this will allocate only the fragments with the lowest push count. Example: If push counts are 1 1 1 0 0, this will only return the size of the last two fragments, even if any of the first three need to be retransmitted. Includes packet overhead.- Parameters:
max- the maximum number of bytes we can send, including packet overhead- Returns:
- 0 to max bytes
needsSending
public boolean needsSending(int fragment) Whether the fragment has not been ACKed.- Parameters:
fragment- the zero-based fragment number to test- Returns:
- true if the fragment has not been ACKed
getLifetime
public long getLifetime()The lifetime.- Returns:
- ms elapsed since the message was created
getStartedOn
public long getStartedOn()When this message was created, for computing lifetime without a repeated clock read in hot loops.- Returns:
- the creation time (ms since epoch)
getSendLifetime
public long getSendLifetime()Network RTT: time since first fragment was sent (excludes queue time). Falls back to total lifetime if message hasn't been sent yet.- Returns:
- the send lifetime
acked
Ack all the fragments in the ack list.- Parameters:
bitfield- the ACK bitfield received from the peer, marking the fragments it holds- Returns:
- true if the message was completely ACKed
acked
public boolean acked(int fragmentNum) Ack this fragment number. For SSU 2 only.- Parameters:
fragmentNum- the zero-based fragment number to clear, ignored when outside the range of fragments in this message- Returns:
- true if the message was completely ACKed
getMaxSends
public int getMaxSends()The max number of sends for any fragment. As of 0.9.49, may be less thangetPushCount()if we pushed only some fragments.- Returns:
- the max sends
getPushCount
public int getPushCount()The number of times we've pushed some fragments. As of 0.9.49, may be greater thangetMaxSends()if we pushed only some fragments.- Returns:
- the push count
push
Add fragments up to the number of bytes allowed by setAllowedSendBytes() Side effects: Clears setAllowedSendBytes. Increments pushCount. Increments maxSends if applicable. Note: With multiple fragments, this will send only the fragments with the lowest push count. Example: If push counts are 1 1 1 0 0, this will only send the last two fragments, even if any of the first three need to be retransmitted.- Parameters:
toSend- list the added fragments are appended to- Returns:
- the number of Fragments added
getFragmentCount
public int getFragmentCount()How many fragments in the message.- Returns:
- the fragment count
getMessageSize
public int getMessageSize()The size of the I2NP message. Does not include any SSU overhead.- Returns:
- the message size
fragmentSize
public int fragmentSize(int fragmentNum) The size in bytes of the fragment. Does NOT include any SSU overhead (SSU2 is 3 for all fragments, + 5 for followon fragments).- Parameters:
fragmentNum- the number of the fragment- Returns:
- the size of the fragment specified by the number
writeFragment
public int writeFragment(byte[] out, int outOffset, int fragmentNum) Write a part of the the message onto the specified buffer.- Parameters:
out- target to writeoutOffset- into outOffset to begin writingfragmentNum- fragment to write (0 indexed)- Returns:
- bytesWritten, NOT including packet overhead
setEnqueueTime
public void setEnqueueTime(long now) For CDQ.- Specified by:
setEnqueueTimein interfaceCDQEntry- Parameters:
now- the enqueue timestamp
getEnqueueTime
public long getEnqueueTime()For CDQ.- Specified by:
getEnqueueTimein interfaceCDQEntry- Returns:
- the enqueue time
drop
setSeqNum
getSeqNum
getPriority
public int getPriority()For CDPQ.- Specified by:
getPriorityin interfacePQEntry- Returns:
- OutNetMessage priority or 1000 for injected
toString