net.i2p.router.transport.udp

## Class PeerState2

- 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 PeerState2
      extends 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 Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `static int` | `DEFAULT_MTU`
    `static int` | `DEFAULT_SSU_IPV4_MTU`
    `static int` | `DEFAULT_SSU_IPV6_MTU`
    `static int` | `MAX_MTU`
    `static int` | `MAX_SSU_IPV4_MTU`
    `static int` | `MAX_SSU_IPV6_MTU`
    `static int` | `MIN_MTU`
    `static int` | `MIN_SSU_IPV4_MTU`
    `static int` | `MIN_SSU_IPV6_MTU`

    - ### Fields inherited from class net.i2p.router.transport.udp.PeerState

      `_context, _dead, _inboundMessages, _isInbound, _keyEstablishedTime, _lastACKSend, _log, _mtu, _packetsReceivedDuplicate, _remoteHostId, _remoteIP, _remoteIPAddress, _remotePeer, _remotePort, _rtt, _transport, _wantACKSendSince, ACK_FREQUENCY, CLOCK_SKEW_FUDGE, LARGE_MTU, MAX_IPV6_MTU, MIN_IPV6_MTU, RETRANSMISSION_PERIOD_WIDTH`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `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)` If inbound, caller MUST immediately call setWeRelayToThemAs() (if nonzero) and sendAck0().

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `(package private) List<OutboundMessageState>` | `allocateSend(long now)` Overridden to retransmit SessionConfirmed also
    `void` | `bitSet(long pktNum)` Callback from SSU2Bitfield.forEachAndNot().
    `(package private) void` | `changeAddress(RemoteHostId id)` Caller should sync; UDPTransport must remove and add to peersByRemoteHost map
    `(package private) void` | `clearWantedACKSendSince()` All acks have been sent.
    `(package private) void` | `confirmedPacketsSent(byte[][] data)` Note that we just sent the SessionConfirmed packets and save them for retransmission.
    `(package private) int` | `finishMessages(long now)` Overridden to expire unacked packets in _sentMessages.
    `(package private) 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.
    `(package private) 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.
    `void` | `fragmentsSent(long pktNum, int length, List<PacketBuilder.Fragment> fragments)` Record the mapping of packet number to what fragments were in it, so we can process acks.
    `SSU2Bitfield` | `getAckedMessages()`
    `(package private) int` | `getDestroyReason()`
    `byte` | `getFlags()` Flag byte to be sent in header
    `long` | `getNextPacketNumber()` Next outbound packet number, starts at 1 for Alice (0 is Session Confirmed) and 0 for Bob
    `protected long` | `getNextPacketNumberNoThrow()` For PeerStateDestroyed only, after we are dead
    `(package private) byte[]` | `getOurIP()` As received in the Address Block in the handshake, or subsequently in the data phase.
    `(package private) int` | `getOurPort()` As received in the Address Block in the handshake, or subsequently in the data phase.
    `(package private) CipherState` | `getRcvCipher()`
    `(package private) long` | `getRcvConnID()`
    `(package private) byte[]` | `getRcvHeaderEncryptKey1()`
    `(package private) byte[]` | `getRcvHeaderEncryptKey2()`
    `SSU2Bitfield` | `getReceivedMessages()`
    `CipherState` | `getSendCipher()` Caller must sync on returned object when encrypting
    `long` | `getSendConnID()`
    `byte[]` | `getSendHeaderEncryptKey1()`
    `byte[]` | `getSendHeaderEncryptKey2()`
    `int` | `getVersion()`
    `void` | `gotACK(long ackThru, int acks, byte[] ranges)`
    `void` | `gotAddress(byte[] ip, int port)`
    `void` | `gotDateTime(long time)`
    `void` | `gotFragment(byte[] data, int off, int len, long messageId, int frag, boolean isLast)` Data must be copied out in this method.
    `void` | `gotI2NP(I2NPMessage msg)`
    `void` | `gotOptions(byte[] options, boolean isHandshake)`
    `void` | `gotPathChallenge(RemoteHostId from, byte[] data)`
    `void` | `gotPathResponse(RemoteHostId from, byte[] data)`
    `void` | `gotPeerTest(int msg, int status, Hash h, byte[] data)`
    `void` | `gotRelayIntro(Hash aliceHash, byte[] data)`
    `void` | `gotRelayRequest(byte[] data)`
    `void` | `gotRelayResponse(int status, byte[] data)`
    `void` | `gotRelayTag(long tag)`
    `void` | `gotRelayTagRequest()`
    `void` | `gotRI(RouterInfo ri, boolean isHandshake, boolean flood)`
    `void` | `gotRIFragment(byte[] data, boolean isHandshake, boolean flood, boolean isGzipped, int frag, int totalFrags)`
    `void` | `gotTermination(int reason, long count)`
    `void` | `gotToken(long token, long expires)`
    `(package private) boolean` | `isDead()`
    `protected void` | `messagePartiallyReceived(long now)` Overridden to use our version of ACKTimer
    `(package private) void` | `receivePacket(RemoteHostId from, UDPPacket packet)` From different than expected source IP/port
    `(package private) void` | `receivePacket(UDPPacket packet)`
    `(package private) void` | `sendAck0()` Send immediate ACK 0 of Session Confirmed.
    `void` | `setDestroyReason(int reason)`
    `(package private) void` | `setOurAddress(byte[] ip, int port)` For initialization by IES2/OES2 only.

    - ### Methods inherited from class net.i2p.router.transport.udp.PeerState

      `acked, add, adjustClockSkew, changePort, dataReceived, dropOutbound, ECNReceived, expireInboundMessages, getClockSkew, getConcurrentSends, getConcurrentSendWindow, getConsecutiveFailedSends, getConsecutiveSendRejections, getInactivityTime, getInboundMessages, getIntroducerTime, getKeyEstablishedTime, getLastACKSend, getLastReceiveTime, getLastSendFullyTime, getLastSendOrPingTime, getLastSendTime, getMayDisconnect, getMessagesReceived, getMessagesSent, getMTU, getNextDelay, getOutboundMessageCount, getPacketsReceived, getPacketsReceivedDuplicate, getPacketsRetransmitted, getPacketsTransmitted, getReceiveBps, getReceiveMTU, getRemoteHostId, getRemoteIP, getRemoteIPAddress, getRemotePeer, getRemotePort, getRTO, getRTT, getRTTDeviation, getSendBps, getSendWindowBytes, getSendWindowBytesRemaining, getSlowStartThreshold, getTheyRelayToUsAs, getTransport, getWeRelayToThemAs, highestSeqNumAcked, incrementConsecutiveFailedSends, isBacklogged, isInbound, isIPv6, loadFrom, messageFullyReceived, messagePartiallyReceived, messageRetransmitted, packetReceived, packetsTransmitted, setHisMTU, setIntroducerTime, setLastPingTime, setLastReceiveTime, setLastSendTime, setMayDisconnect, setTheyRelayToUsAs, setWeRelayToThemAs, shouldRequestImmediateAck, toString`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

    - ### Methods inherited from interface net.i2p.router.transport.udp.SSU2Sender

      `getMTU, getRemoteHostId, getRemoteIPAddress, getRemotePort, isIPv6`

- - ### Field Detail

    - #### DEFAULT_MTU

          public static final int DEFAULT_MTU

      See Also:
        Constant Field Values

    - #### DEFAULT_SSU_IPV4_MTU

          public static final int DEFAULT_SSU_IPV4_MTU

      See Also:
        Constant Field Values

    - #### DEFAULT_SSU_IPV6_MTU

          public static final int DEFAULT_SSU_IPV6_MTU

      See Also:
        Constant Field Values

    - #### MAX_MTU

          public static final int MAX_MTU

      See Also:
        Constant Field Values

    - #### MAX_SSU_IPV4_MTU

          public static final int MAX_SSU_IPV4_MTU

      See Also:
        Constant Field Values

    - #### MAX_SSU_IPV6_MTU

          public static final int MAX_SSU_IPV6_MTU

      See Also:
        Constant Field Values

    - #### MIN_MTU

          public static final int MIN_MTU

      See Also:
        Constant Field Values

    - #### MIN_SSU_IPV4_MTU

          public static final int MIN_SSU_IPV4_MTU

      See Also:
        Constant Field Values

    - #### MIN_SSU_IPV6_MTU

          public static final int MIN_SSU_IPV6_MTU

      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### 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)

      If inbound, caller MUST immediately call setWeRelayToThemAs() (if nonzero) and sendAck0().
      Parameters:
        `rtt` - from the EstablishState, or 0 if not available

  - ### Method Detail

    - #### allocateSend

          List<OutboundMessageState> allocateSend(long now)

      Overridden to retransmit SessionConfirmed also
      Overrides:
        `allocateSend` in class `PeerState`
      Returns:
        allocated messages to send (never empty), or null if no messages or no resources

    - #### bitSet

          public void bitSet(long pktNum)

      Callback from SSU2Bitfield.forEachAndNot(). A new ack was received.
      Specified by:
        `bitSet` in interface `SSU2Bitfield.Callback`

    - #### changeAddress

          void changeAddress(RemoteHostId id)

      Caller should sync; UDPTransport must remove and add to peersByRemoteHost map

    - #### clearWantedACKSendSince

          void clearWantedACKSendSince()

      All acks have been sent.
      Overrides:
        `clearWantedACKSendSince` in class `PeerState`

    - #### 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.

    - #### finishMessages

          int finishMessages(long now)

      Overridden to expire unacked packets in _sentMessages. These will remain unacked if lost; fragments will be retransmitted in a new packet.
      Overrides:
        `finishMessages` in class `PeerState`
      Parameters:
        `now` - current time in milliseconds for expiration checks
      Returns:
        number of active outbound messages remaining

    - #### 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)

    - #### 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)

    - #### fragmentsSent

          public void fragmentsSent(long pktNum,
                                    int length,
                                    List<PacketBuilder.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:
        `length` - including ip/udp header, for logging only

    - #### getAckedMessages

          public SSU2Bitfield getAckedMessages()

      Specified by:
        `getAckedMessages` in interface `SSU2Sender`

    - #### getDestroyReason

          int getDestroyReason()

      Returns:
        0 (REASON_UNSPEC) if unset

    - #### getFlags

          public byte getFlags()

      Flag byte to be sent in header
      Specified by:
        `getFlags` in interface `SSU2Sender`

    - #### getNextPacketNumber

          public long getNextPacketNumber()
                                   throws IOException

      Next outbound packet number, starts at 1 for Alice (0 is Session Confirmed) and 0 for Bob
      Specified by:
        `getNextPacketNumber` in interface `SSU2Sender`
      Throws:
        `IOException`

    - #### getNextPacketNumberNoThrow

          protected long getNextPacketNumberNoThrow()

      For PeerStateDestroyed only, after we are dead

    - #### 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.

    - #### getOurPort

          int getOurPort()

      As received in the Address Block in the handshake, or subsequently in the data phase. Unvalidated.

    - #### getRcvCipher

          CipherState getRcvCipher()

    - #### getRcvConnID

          long getRcvConnID()

    - #### getRcvHeaderEncryptKey1

          byte[] getRcvHeaderEncryptKey1()

    - #### getRcvHeaderEncryptKey2

          byte[] getRcvHeaderEncryptKey2()

    - #### getReceivedMessages

          public SSU2Bitfield getReceivedMessages()

      Specified by:
        `getReceivedMessages` in interface `SSU2Sender`

    - #### getSendCipher

          public CipherState getSendCipher()

      Caller must sync on returned object when encrypting
      Specified by:
        `getSendCipher` in interface `SSU2Sender`

    - #### getSendConnID

          public long getSendConnID()

      Specified by:
        `getSendConnID` in interface `SSU2Sender`

    - #### getSendHeaderEncryptKey1

          public byte[] getSendHeaderEncryptKey1()

      Specified by:
        `getSendHeaderEncryptKey1` in interface `SSU2Sender`

    - #### getSendHeaderEncryptKey2

          public byte[] getSendHeaderEncryptKey2()

      Specified by:
        `getSendHeaderEncryptKey2` in interface `SSU2Sender`

    - #### getVersion

          public int getVersion()

      Overrides:
        `getVersion` in class `PeerState`

    - #### gotACK

          public void gotACK(long ackThru,
                             int acks,
                             byte[] ranges)

      Specified by:
        `gotACK` in interface `SSU2Payload.PayloadCallback`
        `ranges` - null if none

    - #### gotAddress

          public void gotAddress(byte[] ip,
                                 int port)

      Specified by:
        `gotAddress` in interface `SSU2Payload.PayloadCallback`

    - #### gotDateTime

          public void gotDateTime(long time)

      Specified by:
        `gotDateTime` in interface `SSU2Payload.PayloadCallback`

    - #### gotFragment

          public void gotFragment(byte[] data,
                                  int off,
                                  int len,
                                  long messageId,
                                  int frag,
                                  boolean isLast)
                           throws DataFormatException

      Description copied from interface: `SSU2Payload.PayloadCallback`
      Data must be copied out in this method. Data starts at the 9 byte header for fragment 0.
      Specified by:
        `gotFragment` in interface `SSU2Payload.PayloadCallback`
        `off` - offset in data
        `len` - length of data to copy
      Throws:
        `DataFormatException`

    - #### gotI2NP

          public void gotI2NP(I2NPMessage msg)

      Specified by:
        `gotI2NP` in interface `SSU2Payload.PayloadCallback`

    - #### gotOptions

          public void gotOptions(byte[] options,
                                 boolean isHandshake)

      Specified by:
        `gotOptions` in interface `SSU2Payload.PayloadCallback`
        `isHandshake` - true only for message 3 part 2

    - #### gotPathChallenge

          public void gotPathChallenge(RemoteHostId from,
                                       byte[] data)

      Specified by:
        `gotPathChallenge` in interface `SSU2Payload.PayloadCallback`
      Parameters:
        `from` - null if unknown

    - #### gotPathResponse

          public void gotPathResponse(RemoteHostId from,
                                      byte[] data)

      Specified by:
        `gotPathResponse` in interface `SSU2Payload.PayloadCallback`
      Parameters:
        `from` - null if unknown

    - #### gotPeerTest

          public void gotPeerTest(int msg,
                                  int status,
                                  Hash h,
                                  byte[] data)

      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

    - #### gotRelayIntro

          public void gotRelayIntro(Hash aliceHash,
                                    byte[] data)

      Specified by:
        `gotRelayIntro` in interface `SSU2Payload.PayloadCallback`
        `data` - excludes flag, includes signature

    - #### gotRelayRequest

          public void gotRelayRequest(byte[] data)

      Specified by:
        `gotRelayRequest` in interface `SSU2Payload.PayloadCallback`
      Parameters:
        `data` - excludes flag, includes signature

    - #### gotRelayResponse

          public void gotRelayResponse(int status,
                                       byte[] data)

      Specified by:
        `gotRelayResponse` in interface `SSU2Payload.PayloadCallback`
      Parameters:
        `status` - 0 = accept, 1-255 = reject
        `data` - excludes flag, includes signature

    - #### gotRelayTag

          public void gotRelayTag(long tag)

      Specified by:
        `gotRelayTag` in interface `SSU2Payload.PayloadCallback`

    - #### gotRelayTagRequest

          public void gotRelayTagRequest()

      Specified by:
        `gotRelayTagRequest` in interface `SSU2Payload.PayloadCallback`

    - #### gotRI

          public void gotRI(RouterInfo ri,
                            boolean isHandshake,
                            boolean flood)
                     throws DataFormatException

      Specified by:
        `gotRI` in interface `SSU2Payload.PayloadCallback`
      Parameters:
        `ri` - will already be validated
        `isHandshake` - true only for message 3 part 2
      Throws:
        `DataFormatException`

    - #### gotRIFragment

          public void gotRIFragment(byte[] data,
                                    boolean isHandshake,
                                    boolean flood,
                                    boolean isGzipped,
                                    int frag,
                                    int totalFrags)

      Specified by:
        `gotRIFragment` in interface `SSU2Payload.PayloadCallback`
      Parameters:
        `data` - is first gzipped and then fragmented
        `isHandshake` - true only for message 3 part 2

    - #### gotTermination

          public void gotTermination(int reason,
                                     long count)

      Specified by:
        `gotTermination` in interface `SSU2Payload.PayloadCallback`
        `count` - in theory could wrap around to negative, but very unlikely

    - #### gotToken

          public void gotToken(long token,
                               long expires)

      Specified by:
        `gotToken` in interface `SSU2Payload.PayloadCallback`

    - #### isDead

          boolean isDead()

    - #### messagePartiallyReceived

          protected void messagePartiallyReceived(long now)

      Overridden to use our version of ACKTimer
      Overrides:
        `messagePartiallyReceived` in class `PeerState`

    - #### receivePacket

          void receivePacket(RemoteHostId from,
                             UDPPacket packet)

      From different than expected source IP/port
      Parameters:
        `from` - source address
        `packet` - fully encrypted, header and body decryption will be done here

    - #### receivePacket

          void receivePacket(UDPPacket packet)

      Parameters:
        `packet` - fully encrypted, header and body decryption will be done here

    - #### sendAck0

          void sendAck0()

      Send immediate ACK 0 of Session Confirmed. Inbound only. Bundle relay tag if requested, see InboundEstablishState2.

    - #### setDestroyReason

          public void setDestroyReason(int reason)

      Specified by:
        `setDestroyReason` in interface `SSU2Sender`

    - #### setOurAddress

          void setOurAddress(byte[] ip,
                             int port)

      For initialization by IES2/OES2 only.