java.lang.Object
net.i2p.router.transport.udp.PeerState
net.i2p.router.transport.udp.PeerState2
All Implemented Interfaces:
SSU2Bitfield.Callback, SSU2Payload.PayloadCallback, SSU2Sender

public class PeerState2extends PeerState implements SSU2Payload.PayloadCallback, SSU2Bitfield.Callback, SSU2Sender
Contain all of the state about a UDP connection to a peer. This is instantiated only after a connection is fully established.

Public only for UI peers page. Not a public API, not for external use.

SSU2 only.

  • Field Details

    • _sendConnID

      private final long _sendConnID
      Connection id we send with.
    • _rcvConnID

      private final long _rcvConnID
      Connection id we receive with.
    • _packetNumber

      private final AtomicLong _packetNumber
      Next SSU2 packet number to send.
    • MAX_PACKET_NUMBER

      private static final long MAX_PACKET_NUMBER
      Last usable outbound packet number, see getNextPacketNumber(). @since 0.9.71+
      See Also:
    • _lastAckHashCode

      private final AtomicInteger _lastAckHashCode
      Hash of the last ack sent, to skip duplicates.
    • _sendCha

      private final CipherState _sendCha
      ChaCha20 state for encrypting sent packets.
    • _rcvCha

      private final CipherState _rcvCha
      ChaCha20 state for decrypting received packets.
    • _sendHeaderEncryptKey1

      private final byte[] _sendHeaderEncryptKey1
      First header encryption key for sending.
    • _rcvHeaderEncryptKey1

      private final byte[] _rcvHeaderEncryptKey1
      First header encryption key for receiving.
    • _sendHeaderEncryptKey2

      private final byte[] _sendHeaderEncryptKey2
      Second header encryption key for sending.
    • _rcvHeaderEncryptKey2

      private final byte[] _rcvHeaderEncryptKey2
      Second header encryption key for receiving.
    • _receivedMessages

      private final SSU2Bitfield _receivedMessages
      Bitfield of received message numbers.
    • _ackedMessages

      private final SSU2Bitfield _ackedMessages
      PS1 has _ackedMessages which is a map of message ID to sequence number. Here we have the reverse, a bitfield of acked packet (sequence) numbers, and map of unacked packet (sequence) numbers to the fragments that packet contained.
    • _sentMessages

      private final ConcurrentHashMap<Long, List<PacketBuilder2.Fragment>> _sentMessages
      Sent messages awaiting acks, by message id.
    • _ackTimer

      private final PeerState2.ACKTimer _ackTimer
      Timer scheduling acks and retransmits.
    • _sentMessagesLastExpired

      private long _sentMessagesLastExpired
      When sent messages were last expired.
    • _sentMessagesExpiryCursor

      private final ArrayDeque<Map.Entry<Long, List<PacketBuilder2.Fragment>>> _sentMessagesExpiryCursor
      Incremental expiry cursor over a snapshot of _sentMessages, so a tick examines a bounded number of entries instead of the whole map. Only touched from the PacketPusher thread via finishAndAllocate().
    • _ourIP

      private volatile byte[] _ourIP
      Our IP as the peer sees it.
    • _ourPort

      private volatile int _ourPort
      Our port as the peer sees it.
    • _destroyReason

      private volatile int _destroyReason
      Reason code for destroying this state.
    • _sessConfForReTX

      private byte[][] _sessConfForReTX
      Session Confirmed packets held for retransmission.
    • _sessConfSentTime

      private long _sessConfSentTime
      When a Session Confirmed was last sent.
    • _sessConfSentCount

      private int _sessConfSentCount
      Session Confirmed retransmit attempts so far.
    • _migrationLock

      private final Object _migrationLock
      Lock for the connection migration state.
    • _migrationState

      private PeerState2.MigrationState _migrationState
      Current connection migration state.
    • _migrationStarted

      private long _migrationStarted
      When the current migration started.
    • _migrationNextSendTime

      private long _migrationNextSendTime
      When the next migration path challenge is due.
    • _pathChallengeData

      private byte[] _pathChallengeData
      Data of the path challenge we sent.
    • _pathChallengeSendCount

      private long _pathChallengeSendCount
      Path challenges sent for the current migration.
    • _pendingRemoteHostId

      private RemoteHostId _pendingRemoteHostId
      New host id pending confirmation during migration.
    • MAX_PATH_CHALLENGE_SENDS

      static final int MAX_PATH_CHALLENGE_SENDS
      Path challenge retransmissions before the migration is declared expired.
      See Also:
    • MAX_PATH_CHALLENGE_TIME

      static final long MAX_PATH_CHALLENGE_TIME
      Total time a path challenge may span, in ms, before it is declared expired.
      See Also:
    • PATH_CHALLENGE_DELAY

      static final long PATH_CHALLENGE_DELAY
      Base interval between path challenge sends in ms, doubled per retransmission.
      See Also:
    • MIN_SSU_IPV4_MTU

      public static final int MIN_SSU_IPV4_MTU
      MIN_SSU_IPV4_MTU.
      See Also:
    • MAX_SSU_IPV4_MTU

      public static final int MAX_SSU_IPV4_MTU
      MAX_SSU_IPV4_MTU.
      See Also:
    • DEFAULT_SSU_IPV4_MTU

      public static final int DEFAULT_SSU_IPV4_MTU
      DEFAULT_SSU_IPV4_MTU.
      See Also:
    • MIN_SSU_IPV6_MTU

      public static final int MIN_SSU_IPV6_MTU
      MIN_SSU_IPV6_MTU.
      See Also:
    • MAX_SSU_IPV6_MTU

      public static final int MAX_SSU_IPV6_MTU
      MAX_SSU_IPV6_MTU.
      See Also:
    • DEFAULT_SSU_IPV6_MTU

      public static final int DEFAULT_SSU_IPV6_MTU
      DEFAULT_SSU_IPV6_MTU.
      See Also:
    • MIN_MTU

      public static final int MIN_MTU
      Smallest MTU we will advertise to SSU2 peers, in bytes.
      See Also:
    • MAX_MTU

      public static final int MAX_MTU
      Largest MTU we will advertise to SSU2 peers, in bytes.
      See Also:
    • DEFAULT_MTU

      public static final int DEFAULT_MTU
      MTU advertised unless the profile overrides it.
      See Also:
    • MIN_MLKEM768_IPV4_MTU

      public static final int MIN_MLKEM768_IPV4_MTU
      MIN_MLKEM768_IPV4_MTU.
      See Also:
    • MIN_MLKEM768_IPV6_MTU

      public static final int MIN_MLKEM768_IPV6_MTU
      MIN_MLKEM768_IPV6_MTU.
      See Also:
    • BITFIELD_SIZE

      private static final int BITFIELD_SIZE
      Message numbers tracked in the received bitfield.
      See Also:
    • MAX_SESS_CONF_RETX

      private static final int MAX_SESS_CONF_RETX
      Session Confirmed retransmits before giving up.
      See Also:
    • _sentMessagesCleanTime

      private static volatile long _sentMessagesCleanTime
      Configurable sent-messages sweep interval. Default 60s, shortened under load.
    • SENT_MESSAGES_EXPIRE_BATCH

      private static final int SENT_MESSAGES_EXPIRE_BATCH
      Max _sentMessages entries examined per expireSentMessages(long) call. @since 0.9.71+.
      See Also:
  • Constructor Details

    • PeerState2

      public PeerState2(RouterContext ctx, UDPTransport transport, InetSocketAddress remoteAddress, Hash remotePeer, boolean isInbound, int rtt, CipherState sendCha, CipherState rcvCha, long sendID, long rcvID, byte[] sendHdrKey1, byte[] sendHdrKey2, byte[] rcvHdrKey2)
      A session with a remote peer over SSU2: the connection ids, the four cipher states and the header encryption keys are all fixed here, so the transport can build one without a separate handshake step.

      If inbound, caller MUST immediately call setWeRelayToThemAs() (if nonzero) and sendAck0().

      Parameters:
      ctx - the router context
      transport - the UDP transport this session runs on
      remoteAddress - the peer's address, which may change on migration
      remotePeer - the peer's router hash
      isInbound - true if the peer opened the session, false if we did
      rtt - from the EstablishState, or 0 if not available
      sendCha - the outbound cipher state for payload blocks
      rcvCha - the inbound cipher state for payload blocks
      sendID - the connection id we send in every block header
      rcvID - the connection id the peer sends in every block header
      sendHdrKey1 - the first outbound header encryption key
      sendHdrKey2 - the second outbound header encryption key
      rcvHdrKey2 - the second inbound header encryption key
  • Method Details

    • shouldLogDebug

      private boolean shouldLogDebug()
      Whether debug logging is on for this peer.
      Returns:
      true if debug logging is enabled
    • getSentMessagesCleanTime

      public static long getSentMessagesCleanTime()
      Current sent-messages cleanup interval.
      Returns:
      current sent-messages cleanup interval in ms
    • setSentMessagesCleanTime

      public static void setSentMessagesCleanTime(long ms)
      Sent-messages cleanup interval, called by Tuner.
      Parameters:
      ms - cleanup interval in ms, clamped to [2000, 300000]
    • sendAck0

      void sendAck0()
      Send immediate ACK 0 of Session Confirmed. Inbound only. Bundle relay tag if requested, see InboundEstablishState2.
    • getVersion

      public int getVersion()
      The version.
      Overrides:
      getVersion in class PeerState
      Returns:
      2, as this class implements SSU2
    • fragmentSize

      int fragmentSize()
      How much payload data can we shove in there? This is 5 bytes too low for first or only fragment, because the 9 byte I2NP header is included in that fragment. Does NOT leave any room for acks with a full-size fragment.
      Overrides:
      fragmentSize in class PeerState
      Returns:
      MTU - 68 (IPv4), MTU - 88 (IPv6)
    • fragmentOverhead

      int fragmentOverhead()
      Packet overhead This is 5 bytes too high for first or only fragment, because the 9 byte I2NP header is included in that fragment. Does NOT leave any room for acks with a full-size fragment.
      Overrides:
      fragmentOverhead in class PeerState
      Returns:
      68 (IPv4), 88 (IPv6)
    • clearWantedACKSendSince

      void clearWantedACKSendSince()
      All acks have been sent.
      Overrides:
      clearWantedACKSendSince in class PeerState
    • messagePartiallyReceived

      protected void messagePartiallyReceived(long now)
      Overridden to use our version of ACKTimer.
      Overrides:
      messagePartiallyReceived in class PeerState
      Parameters:
      now - the current time
    • expireSentMessages

      private void expireSentMessages(long now)
      Expire complete or timed-out entries from _sentMessages, walking an incremental cursor instead of rescanning the whole map and every fragment list on every tick.

      The cursor holds a snapshot of the map taken when it runs dry; entries acked in the meantime are skipped by the identity check, and newly added entries are picked up on the next refill. An entry is removed only when every fragment's message is complete or expired, so it never expires early. One pass covers the whole cursor, so retention matches the old full scan's single tick.

      Only called from finishAndAllocate(long) on the PacketPusher thread, so the cursor needs no synchronization. Failure detection is unaffected: that is the "ahead > BITFIELD_SIZE" check in finishAndAllocate(long), which runs on its own schedule.

      Parameters:
      now - current time, for the expiry test
    • finishAndAllocate

      List<OutboundMessageState> finishAndAllocate(long now)
      Single-pass combined cleanup + send allocation, overriding the base class to incorporate SSU2-specific _sentMessages cleanup and SessionConfirmed retransmit logic.
      Overrides:
      finishAndAllocate in class PeerState
      Parameters:
      now - current time in ms, used as the expiry base for the messages that are allocated here
      Returns:
      messages to send, or null if none ready
    • checkRetransmitSessionConfirmed

      private boolean checkRetransmitSessionConfirmed(long now, boolean force)
      Only call for outbound, if we don't have ack 0 yet.
      Parameters:
      now - the current time in ms for the retransmit timer
      force - ignore timer, always send
      Returns:
      success, false if total fail
    • checkRetransmitSessionConfirmed2

      private boolean checkRetransmitSessionConfirmed2(long now, boolean force)
      Only call for outbound, if we don't have ack 0 yet.
      Parameters:
      now - the current time in ms for the retransmit timer
      force - ignore timer, always send
      Returns:
      success, false if total fail
    • getNextPacketNumber

      public long getNextPacketNumber() throws IOException
      Next outbound packet number, starts at 1 for Alice (0 is Session Confirmed) and 0 for Bob. The packet number is a 4-byte header field and doubles as the ChaCha20 and Poly1305 nonce, so the session must not outlive the number space - wrapping would silently reuse keystream and the Poly1305 key. A busy router can burn 2^32 numbers in hours, hence the guard. Leaves 256 numbers of headroom for the destroy packets sent after death.
      Specified by:
      getNextPacketNumber in interface SSU2Sender
      Returns:
      the next packet number
      Throws:
      IOException - if the number space is exhausted, killing the session so the caller re-handshakes with fresh keys
    • getNextPacketNumberNoThrow

      protected long getNextPacketNumberNoThrow()
      For PeerStateDestroyed only, after we are dead.
      Returns:
      the next packet number no throw
    • getSendConnID

      public long getSendConnID()
      The send connection ID. For PeerStateDestroyed only, after we are dead.
      Specified by:
      getSendConnID in interface SSU2Sender
      Returns:
      the send conn i d
    • getSendCipher

      public CipherState getSendCipher()
      Caller must sync on returned object when encrypting.
      Specified by:
      getSendCipher in interface SSU2Sender
      Returns:
      the send cipher
    • getSendHeaderEncryptKey1

      public byte[] getSendHeaderEncryptKey1()
      The send header encryption key 1. Caller must sync on returned object when encrypting.
      Specified by:
      getSendHeaderEncryptKey1 in interface SSU2Sender
      Returns:
      the send header encrypt key1
    • getSendHeaderEncryptKey2

      public byte[] getSendHeaderEncryptKey2()
      The send header encryption key 2. Caller must sync on returned object when encrypting.
      Specified by:
      getSendHeaderEncryptKey2 in interface SSU2Sender
      Returns:
      the send header encrypt key2
    • setDestroyReason

      public void setDestroyReason(int reason)
      Record why the peer was destroyed, for the Destroy message.
      Specified by:
      setDestroyReason in interface SSU2Sender
      Parameters:
      reason - the SSU2Util termination code, echoed to the peer in a SessionDestroy and ignored once destroyed
    • getRcvConnID

      long getRcvConnID()
      The connection ID we expect to receive packets with.
      Returns:
      the receive connection ID
    • getRcvHeaderEncryptKey1

      byte[] getRcvHeaderEncryptKey1()
      The first header encryption key for received packets.
      Returns:
      the receive header key 1
    • getRcvHeaderEncryptKey2

      byte[] getRcvHeaderEncryptKey2()
      The second header encryption key for received packets.
      Returns:
      the receive header key 2
    • getDestroyReason

      int getDestroyReason()
      The destroy reason, for PeerStateDestroyed only, after we are dead.
      Returns:
      0 (REASON_UNSPEC) if unset
    • getRcvCipher

      CipherState getRcvCipher()
      The inbound cipher state, paired with the peer's first header key.
      Returns:
      the inbound payload cipher state
    • setOurAddress

      void setOurAddress(byte[] ip, int port)
      For initialization by IES2/OES2 only.
      Parameters:
      ip - our address as the peer will see it, 4 or 16 bytes
      port - our port as the peer will see it
    • getOurIP

      byte[] getOurIP()
      As received in the Address Block in the handshake, or subsequently in the data phase. Unvalidated. Also, if a transient IPv6 address, may be deprecated and not match our current non-deprecated IPv6 address.
      Returns:
      our address as the peer sees it, 4 or 16 bytes, or null if unset
    • getOurPort

      int getOurPort()
      As received in the Address Block in the handshake, or subsequently in the data phase. Unvalidated.
      Returns:
      our port as the peer sees it, or 0 if unset
    • getReceivedMessages

      public SSU2Bitfield getReceivedMessages()
      Bitfield of messages received from the peer.
      Specified by:
      getReceivedMessages in interface SSU2Sender
      Returns:
      the received messages
    • getAckedMessages

      public SSU2Bitfield getAckedMessages()
      Bitfield of messages acknowledged to the peer.
      Specified by:
      getAckedMessages in interface SSU2Sender
      Returns:
      the acked messages
    • receivePacket

      void receivePacket(UDPPacket packet)
      Receives and decrypts the given packet.
      Parameters:
      packet - fully encrypted, header and body decryption will be done here
    • receivePacket

      void receivePacket(RemoteHostId from, UDPPacket packet)
      From different than expected source IP/port.
      Parameters:
      from - source address the packet did not come from; a mismatch causes the packet to be dropped
      packet - fully encrypted, header and body decryption will be done here
    • handleMigrationNone

      private boolean handleMigrationNone(RemoteHostId from, long n, UDPPacket packet)
      Connection migration attempt while in MIGRATION_STATE_NONE.

      A packet from a host different from the current remote host starts a migration only when it passes the pure shouldInitiateMigration(boolean, boolean, boolean, boolean) classifier (IP family match, highest-set ordering rule, validated source). Path Response processing happens earlier in receivePacket, so a completed migration has already reset the state before this runs. Sending is limited only while a challenge is actually outstanding; a refused migration must not freeze the verified path.

      Must be called with _migrationLock held.

      Parameters:
      from - source address of the received packet, or null
      n - packet (sequence) number of the received packet
      packet - the received packet (source address used for the challenge)
      Returns:
      true if sending must be limited while the connection is migrating
    • handleMigrationPending

      private boolean handleMigrationPending(RemoteHostId from, UDPPacket packet)
      Connection migration attempt while in MIGRATION_STATE_PENDING.

      The packet source is classified by the pure decidePendingMigration(long, boolean, boolean, long, long, long) method. This method applies the side effects (cancel/timeout state reset, path-challenge retransmission with exponential backoff).

      Must be called with _migrationLock held.

      Parameters:
      from - source address of the received packet, or null
      packet - the received packet (source address used for retransmission)
      Returns:
      true if sending must be limited while the connection is migrating
    • shouldInitiateMigration

      static boolean shouldInitiateMigration(boolean ipFamilyMatch, boolean isHighestSet, boolean validPort, boolean validIP)
      Decide whether a packet from a new source address may initiate a connection migration while the connection is in MIGRATION_STATE_NONE.

      The source IP family must match the current remote host, the packet must be the highest sequence received so far (QUIC ordering rule, protects against reordered packets driving a migration to an attacker-chosen address), and the source must pass both port and address validation.

      Parameters:
      ipFamilyMatch - true if the source IP family matches the current remote host
      isHighestSet - true if the packet is the highest sequence received so far
      validPort - true if the source port is valid
      validIP - true if the source IP passes transport address validation
      Returns:
      a boolean indicating whether to start the migration challenge
    • decidePendingMigration

      static PeerState2.MigrationPendingDecision decidePendingMigration(long now, boolean fromIsRemote, boolean fromIsPending, long migrationStarted, long sendCount, long nextSendTime)
      Classify what to do with a packet received while the connection is in MIGRATION_STATE_PENDING. Pure decision; side effects are applied by the caller. Order of precedence: the current remote host wins (cancel), the timeout/send-budget check wins over retransmission.
      Parameters:
      now - current time ms
      fromIsRemote - true if the source is the current (pre-migration) remote host
      fromIsPending - true if the source is the pending migration target
      migrationStarted - ms at which the migration was started
      sendCount - number of path challenges already sent
      nextSendTime - ms at which the next retransmission is due
      Returns:
      the pending-migration action to take
    • sendPathChallenge

      private void sendPathChallenge(InetAddress toIP, int toPort)
      Caller must synch on _migrationState.
      Parameters:
      toIP - the address to send the path challenge to
      toPort - the port to send the path challenge to
    • gotDateTime

      public void gotDateTime(long time)
      Process a received DateTime block.
      Specified by:
      gotDateTime in interface SSU2Payload.PayloadCallback
      Parameters:
      time - time in milliseconds since epoch
    • gotOptions

      public void gotOptions(byte[] options, boolean isHandshake)
      Process a received Options block.
      Specified by:
      gotOptions in interface SSU2Payload.PayloadCallback
      Parameters:
      options - the option data
      isHandshake - true only for message 3 part 2
    • gotRI

      public void gotRI(RouterInfo ri, boolean isHandshake, boolean flood) throws DataFormatException
      Process a received RouterInfo block, storing and possibly flooding it.
      Specified by:
      gotRI in interface SSU2Payload.PayloadCallback
      Parameters:
      ri - will already be validated
      isHandshake - true only for message 3 part 2
      flood - true if this is a floodfill router
      Throws:
      DataFormatException - if the RouterInfo block is malformed
    • gotRIFragment

      public void gotRIFragment(byte[] data, boolean isHandshake, boolean flood, boolean isGzipped, int frag, int totalFrags)
      Process a received RouterInfo fragment block.
      Specified by:
      gotRIFragment in interface SSU2Payload.PayloadCallback
      Parameters:
      data - is first gzipped and then fragmented
      isHandshake - true only for message 3 part 2
      flood - true if this is a floodfill router
      isGzipped - true if the data is gzipped
      frag - fragment number (0-based)
      totalFrags - total number of fragments
    • gotAddress

      public void gotAddress(byte[] ip, int port)
      Process a received Address block, updating our external address.
      Specified by:
      gotAddress in interface SSU2Payload.PayloadCallback
      Parameters:
      ip - IP address bytes
      port - the port number to send
    • gotRelayTagRequest

      public void gotRelayTagRequest()
      Process a received RelayTagRequest block, offering a relay tag if possible.
      Specified by:
      gotRelayTagRequest in interface SSU2Payload.PayloadCallback
    • gotRelayTag

      public void gotRelayTag(long tag)
      Process a received RelayTag block.
      Specified by:
      gotRelayTag in interface SSU2Payload.PayloadCallback
      Parameters:
      tag - the relay tag
    • gotRelayRequest

      public void gotRelayRequest(byte[] data)
      Process a received RelayRequest block.
      Specified by:
      gotRelayRequest in interface SSU2Payload.PayloadCallback
      Parameters:
      data - excludes flag, includes signature
    • gotRelayResponse

      public void gotRelayResponse(int status, byte[] data)
      Process a received RelayResponse block.
      Specified by:
      gotRelayResponse in interface SSU2Payload.PayloadCallback
      Parameters:
      status - 0 = accept, 1-255 = reject
      data - excludes flag, includes signature
    • gotRelayIntro

      public void gotRelayIntro(Hash aliceHash, byte[] data)
      Process a received RelayIntro block.
      Specified by:
      gotRelayIntro in interface SSU2Payload.PayloadCallback
      Parameters:
      aliceHash - hash of the introducer
      data - excludes flag, includes signature
    • gotPeerTest

      public void gotPeerTest(int msg, int status, Hash h, byte[] data)
      Process a received PeerTest block.
      Specified by:
      gotPeerTest in interface SSU2Payload.PayloadCallback
      Parameters:
      msg - 1-7
      status - 0 = accept, 1-255 = reject
      h - Alice or Charlie hash for msg 2 and 4, null for msg 1, 3, 5-7
      data - excludes flag, includes signature
    • gotToken

      public void gotToken(long token, long expires)
      Process a received Token block.
      Specified by:
      gotToken in interface SSU2Payload.PayloadCallback
      Parameters:
      token - the session token to attach to the next peer test
      expires - token expiration time in milliseconds
    • gotI2NP

      public void gotI2NP(I2NPMessage msg)
      Process a received I2NP block.
      Specified by:
      gotI2NP in interface SSU2Payload.PayloadCallback
      Parameters:
      msg - the parsed I2NP message
    • gotFragment

      public void gotFragment(byte[] data, int off, int len, long messageId, int frag, boolean isLast) throws DataFormatException
      Process a received Fragment block.
      Specified by:
      gotFragment in interface SSU2Payload.PayloadCallback
      Parameters:
      data - buffer containing fragment data
      off - offset in data
      len - length of data to copy
      messageId - unique message identifier
      frag - fragment number (0-based)
      isLast - whether this is the last fragment
      Throws:
      DataFormatException - if the fragment is malformed
    • gotACK

      public void gotACK(long ackThru, int acks, byte[] ranges)
      Process a received ACK block.
      Specified by:
      gotACK in interface SSU2Payload.PayloadCallback
      Parameters:
      ackThru - highest contiguous sequence number acknowledged
      acks - number of additional acknowledgments beyond ackThru
      ranges - null if none
    • gotTermination

      public void gotTermination(int reason, long count)
      Process a received Termination block.
      Specified by:
      gotTermination in interface SSU2Payload.PayloadCallback
      Parameters:
      reason - termination reason code
      count - in theory could wrap around to negative, but very unlikely
    • gotPathChallenge

      public void gotPathChallenge(RemoteHostId from, byte[] data)
      Process a received PathChallenge block, replying with a PathResponse.
      Specified by:
      gotPathChallenge in interface SSU2Payload.PayloadCallback
      Parameters:
      from - null if unknown
      data - the challenge bytes, which must be copied out
    • gotPathResponse

      public void gotPathResponse(RemoteHostId from, byte[] data)
      Process a received PathResponse block.
      Specified by:
      gotPathResponse in interface SSU2Payload.PayloadCallback
      Parameters:
      from - null if unknown
      data - the response bytes, which must be copied out
    • changeAddress

      void changeAddress(RemoteHostId id)
      Caller should sync; UDPTransport must remove and add to peersByRemoteHost map.
      Parameters:
      id - the new remote host id, carrying both the address and the port
    • receiveMessage

      private void receiveMessage(InboundMessageState state)
      Do what MessageReceiver does, but inline and for SSU2. Will always be more than one fragment.
      Parameters:
      state - the complete multi-fragment message to reassemble and queue
    • fragmentsSent

      public void fragmentsSent(long pktNum, int length, List<PacketBuilder2.Fragment> fragments)
      Record the mapping of packet number to what fragments were in it, so we can process acks.
      Specified by:
      fragmentsSent in interface SSU2Sender
      Parameters:
      pktNum - the packet number the fragments were sent under
      length - including ip/udp header, for logging only
      fragments - fragment list
    • bitSet

      public void bitSet(long pktNum)
      Specified by:
      bitSet in interface SSU2Bitfield.Callback
      Parameters:
      pktNum - the absolute message number that was newly set
    • confirmedPacketsSent

      void confirmedPacketsSent(byte[][] data)
      Note that we just sent the SessionConfirmed packets and save them for retransmission. This is only called the first time. For retransmit see allocateSend() above.
      Parameters:
      data - the SessionConfirmed packet bodies, retained only if this is the first send so a retransmission can resend the same bytes
    • getRetransmitSessionConfirmedPackets

      private UDPPacket[] getRetransmitSessionConfirmedPackets()
      The saved SessionConfirmed packets for retransmission.
      Returns:
      null if not sent or already got the ack
    • getFlags

      public byte getFlags()
      Flag byte to be sent in header.
      Specified by:
      getFlags in interface SSU2Sender
      Returns:
      the header flag byte, 0x01 when the send window has under a third of its capacity left and an immediate ack is requested, otherwise 0
    • isDead

      boolean isDead()
      Whether a SessionDestroy has been sent or received on this session, so the transport can drop the session without a second teardown exchange.
      Returns:
      true once the session has been destroyed
    • sentMessagesSize

      public int sentMessagesSize()
      Number of pending sent-but-unacked packet entries.
      Returns:
      the number of packet entries awaiting an ACK, not a byte count
    • dropOutbound

      void dropOutbound()
      Overridden to also clear sent-but-unacked fragments and cancel ACKTimer. Prevents lingering references from keeping orphaned PeerState2 alive.
      Overrides:
      dropOutbound in class PeerState