java.lang.Object
net.i2p.router.transport.udp.PeerStateDestroyed
- All Implemented Interfaces:
SSU2Payload.PayloadCallback, SSU2Sender
Small, stub version of PeerState2, for handling destroy acks with possible tokens in them.
This is the "closing state" as defined in QUIC RFC-9000 section 10.2.1. Unlike in QUIC, we do increment the packet number for every sent destroy packet. Also, we retain the header and body decryption keys, and we do process any tokens received. We only respond when receiving data or a termination with a non-ack reason.
Does not extend PeerState2 or PeerState.
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate classA timer to send an ack+destroy packet.private classA timer to remove us from the transport list.Field Summary
FieldsModifier and TypeFieldDescriptionprivate final PeerStateDestroyed.ACKTimerTimer scheduling acks and retransmits.private final RouterContextThe router context.private final longWhen the state was destroyed.private intReason code for the destroy.private final PeerStateDestroyed.KillTimerTimer killing this state when it expires.private final LogLogger for the destroyed peer state.private final intThe MTU for sending to the peer.private final AtomicIntegerNext packet number to send.private final CipherStateChaCha20 state for decrypting received packets.private final longConnection id we receive with.private final byte[]First header encryption key for receiving.private final byte[]Second header encryption key for receiving.private final SSU2BitfieldBitfield of received message numbers.private final RemoteHostIdThe peer's host id.private final CipherStateChaCha20 state for encrypting sent packets.private final longConnection id we send with.private final byte[]First header encryption key for sending.private final byte[]Second header encryption key for sending.private final UDPTransportThe SSU transport we serve.protected longRedeclares the base class field: zero means no termination ACK is owed, nonzero is when one first became due.private static final longMaximum lifetime of a destroyed state.private static final longInterval between Destroyed packet retransmits.Constructor Summary
ConstructorsConstructorDescriptionPeerStateDestroyed(RouterContext ctx, UDPTransport transport, PeerState2 peer) This must be called after the first termination or termination ack was sent fromPeerState2, so the next packet number is correct.PeerStateDestroyed(RouterContext ctx, UDPTransport transport, RemoteHostId id, long sendID, long rcvID, CipherState sendCha, CipherState rcvCha, byte[] sendKey1, byte[] sendKey2, byte[] rcvKey2, int reason) Direct from IES2, there was never a PS2.Method Summary
Modifier and TypeMethodDescriptionvoidfragmentsSent(long pktNum, int length, List<PacketBuilder2.Fragment> fragments) Track sent fragments; no-op after destruction.No-op, we don't care what was acked.bytegetFlags()The flags byte.intgetMTU()The MTU.longThe next packet number.(package private) longThe inbound connection ID for this session.The received messages bitfield.The remote host ID.The peer's IP address, built from its host id.intThe remote port.The send cipher.longThe send connection ID.byte[]The first send header encryption key.byte[]The second send header encryption key.voidgotACK(long ackThru, int acks, byte[] ranges) Process a received ACK block; no-op after destruction.voidgotAddress(byte[] ip, int port) Process a received Address block; no-op after destruction.voidgotDateTime(long time) Process a received DateTime block; no-op after destruction.voidgotFragment(byte[] data, int off, int len, long messageId, int frag, boolean isLast) Process a received Fragment block.voidgotI2NP(I2NPMessage msg) Process a received I2NP block.voidgotOptions(byte[] options, boolean isHandshake) Process a received Options block; no-op after destruction.voidgotPathChallenge(RemoteHostId from, byte[] data) Process a received PathChallenge block; no-op after destruction.voidgotPathResponse(RemoteHostId from, byte[] data) Process a received PathResponse block; no-op after destruction.voidgotPeerTest(int msg, int status, Hash h, byte[] data) Process a received PeerTest block.voidgotRelayIntro(Hash aliceHash, byte[] data) Process a received RelayIntro block.voidgotRelayRequest(byte[] data) Process a received RelayRequest block.voidgotRelayResponse(int status, byte[] data) Process a received RelayResponse block.voidgotRelayTag(long tag) Process a received RelayTag block; no-op after destruction.voidProcess a received RelayTagRequest block; no-op after destruction.voidgotRI(RouterInfo ri, boolean isHandshake, boolean flood) Process a received RouterInfo block.voidgotRIFragment(byte[] data, boolean isHandshake, boolean flood, boolean isGzipped, int frag, int totalFrags) Process a received RouterInfo fragment block.voidgotTermination(int reason, long count) Process a received Termination block.voidgotToken(long token, long expires) Process a received Token block.booleanisIPv6()Whether the peer is IPv6.voidkill()Call at transport shutdown or cache eviction.private voidKeeps the state alive while a message is partially received.(package private) voidreceivePacket(RemoteHostId from, UDPPacket packet) Handle one packet received from the given source address.(package private) voidreceivePacket(UDPPacket packet) Handle one packet received from the peer.voidsetDestroyReason(int reason) The destroy reason.toString()String representation of this destroyed peer.
Field Details
_context
The router context._log
Logger for the destroyed peer state._transport
The SSU transport we serve._remoteHostId
The peer's host id._mtu
private final int _mtuThe MTU for sending to the peer._sendConnID
private final long _sendConnIDConnection id we send with._rcvConnID
private final long _rcvConnIDConnection id we receive with._packetNumber
Next packet number to send._sendCha
ChaCha20 state for encrypting sent packets._rcvCha
ChaCha20 state for decrypting received packets._sendHeaderEncryptKey1
private final byte[] _sendHeaderEncryptKey1First header encryption key for sending._rcvHeaderEncryptKey1
private final byte[] _rcvHeaderEncryptKey1First header encryption key for receiving._sendHeaderEncryptKey2
private final byte[] _sendHeaderEncryptKey2Second header encryption key for sending._rcvHeaderEncryptKey2
private final byte[] _rcvHeaderEncryptKey2Second header encryption key for receiving._receivedMessages
Bitfield of received message numbers._ackTimer
Timer scheduling acks and retransmits._killTimer
Timer killing this state when it expires._destroyedOn
private final long _destroyedOnWhen the state was destroyed._wantACKSendSince
protected volatile long _wantACKSendSinceRedeclares the base class field: zero means no termination ACK is owed, nonzero is when one first became due._destroyReason
private volatile int _destroyReasonReason code for the destroy.MAX_LIFETIME
private static final long MAX_LIFETIMEMaximum lifetime of a destroyed state.- See Also:
TERMINATION_RETX_TIME
private static final long TERMINATION_RETX_TIMEInterval between Destroyed packet retransmits.- See Also:
Constructor Details
PeerStateDestroyed
This must be called after the first termination or termination ack was sent fromPeerState2, so the next packet number is correct.- Parameters:
ctx- the router contexttransport- the UDP transportpeer- that just sent (or received and sent) a termination
PeerStateDestroyed
public PeerStateDestroyed(RouterContext ctx, UDPTransport transport, RemoteHostId id, long sendID, long rcvID, CipherState sendCha, CipherState rcvCha, byte[] sendKey1, byte[] sendKey2, byte[] rcvKey2, int reason) Direct from IES2, there was never a PS2. Caller must send termination after creating.- Parameters:
ctx- the router contexttransport- the UDP transportid- the remote host identifiersendID- the next outbound session IDrcvID- the next inbound session IDsendCha- outbound cipher statercvCha- inbound cipher statesendKey1- first half of the outbound keysendKey2- second half of the outbound keyrcvKey2- second half of the inbound keyreason- the termination reason code
Method Details
kill
public void kill()Call at transport shutdown or cache eviction.getRemoteHostId
The remote host ID.- Specified by:
getRemoteHostIdin interfaceSSU2Sender- Returns:
- the peer's IP and port as a RemoteHostId
isIPv6
public boolean isIPv6()Whether the peer is IPv6.- Specified by:
isIPv6in interfaceSSU2Sender- Returns:
- whether IPv6
getRemoteIPAddress
The peer's IP address, built from its host id.- Specified by:
getRemoteIPAddressin interfaceSSU2Sender- Returns:
- the peer's address
getRemotePort
public int getRemotePort()The remote port.- Specified by:
getRemotePortin interfaceSSU2Sender- Returns:
- the peer's UDP port
getMTU
public int getMTU()The MTU.- Specified by:
getMTUin interfaceSSU2Sender- Returns:
- the maximum UDP payload size in bytes for this peer
getNextPacketNumber
public long getNextPacketNumber()The next packet number.- Specified by:
getNextPacketNumberin interfaceSSU2Sender- Returns:
- the number for the next outbound packet, then increments
getSendConnID
public long getSendConnID()The send connection ID.- Specified by:
getSendConnIDin interfaceSSU2Sender- Returns:
- the send conn i d
getSendCipher
The send cipher.- Specified by:
getSendCipherin interfaceSSU2Sender- Returns:
- the Noise cipher state for outbound packets
getSendHeaderEncryptKey1
public byte[] getSendHeaderEncryptKey1()The first send header encryption key.- Specified by:
getSendHeaderEncryptKey1in interfaceSSU2Sender- Returns:
- the send header encrypt key1
getSendHeaderEncryptKey2
public byte[] getSendHeaderEncryptKey2()The second send header encryption key.- Specified by:
getSendHeaderEncryptKey2in interfaceSSU2Sender- Returns:
- the send header encrypt key2
setDestroyReason
public void setDestroyReason(int reason) The destroy reason.- Specified by:
setDestroyReasonin interfaceSSU2Sender- Parameters:
reason- theSSU2Utiltermination code, echoed to the peer in a SessionDestroy and ignored once destroyed
getReceivedMessages
The received messages bitfield.- Specified by:
getReceivedMessagesin interfaceSSU2Sender- Returns:
- the received messages
getAckedMessages
No-op, we don't care what was acked.- Specified by:
getAckedMessagesin interfaceSSU2Sender- Returns:
- null always, we don't care what was acked
fragmentsSent
Track sent fragments; no-op after destruction.- Specified by:
fragmentsSentin interfaceSSU2Sender- Parameters:
pktNum- the packet number the fragments were sent underlength- the total payload length those fragments add up tofragments- fragment list
getFlags
public byte getFlags()The flags byte.- Specified by:
getFlagsin interfaceSSU2Sender- Returns:
- zero, as a destroyed session sends no packets
getRcvConnID
long getRcvConnID()The inbound connection ID for this session.- Returns:
- the connection ID
messagePartiallyReceived
private void messagePartiallyReceived()Keeps the state alive while a message is partially received.receivePacket
Handle one packet received from the peer.- Parameters:
packet- fully encrypted, header and body decryption will be done here
receivePacket
Handle one packet received from the given source address.- Parameters:
from- the address the packet was received frompacket- fully encrypted, header and body decryption will be done here
gotDateTime
public void gotDateTime(long time) Process a received DateTime block; no-op after destruction.- Specified by:
gotDateTimein interfaceSSU2Payload.PayloadCallback- Parameters:
time- time in milliseconds since epoch
gotOptions
public void gotOptions(byte[] options, boolean isHandshake) Process a received Options block; no-op after destruction.- Specified by:
gotOptionsin interfaceSSU2Payload.PayloadCallback- Parameters:
options- the option dataisHandshake- true only for message 3 part 2
gotRI
Process a received RouterInfo block.- Specified by:
gotRIin interfaceSSU2Payload.PayloadCallback- Parameters:
ri- will already be validatedisHandshake- true only for message 3 part 2flood- true if this is a floodfill router
gotRIFragment
public void gotRIFragment(byte[] data, boolean isHandshake, boolean flood, boolean isGzipped, int frag, int totalFrags) Process a received RouterInfo fragment block.- Specified by:
gotRIFragmentin interfaceSSU2Payload.PayloadCallback- Parameters:
data- is first gzipped and then fragmentedisHandshake- true only for message 3 part 2flood- true if this is a floodfill routerisGzipped- true if the data is gzippedfrag- fragment number (0-based)totalFrags- total number of fragments
gotAddress
public void gotAddress(byte[] ip, int port) Process a received Address block; no-op after destruction.- Specified by:
gotAddressin interfaceSSU2Payload.PayloadCallback- Parameters:
ip- IP address bytesport- the port number to send
gotRelayTagRequest
public void gotRelayTagRequest()Process a received RelayTagRequest block; no-op after destruction.- Specified by:
gotRelayTagRequestin interfaceSSU2Payload.PayloadCallback
gotRelayTag
public void gotRelayTag(long tag) Process a received RelayTag block; no-op after destruction.- Specified by:
gotRelayTagin interfaceSSU2Payload.PayloadCallback- Parameters:
tag- the relay tag
gotRelayRequest
public void gotRelayRequest(byte[] data) Process a received RelayRequest block.- Specified by:
gotRelayRequestin interfaceSSU2Payload.PayloadCallback- Parameters:
data- excludes flag, includes signature
gotRelayResponse
public void gotRelayResponse(int status, byte[] data) Process a received RelayResponse block.- Specified by:
gotRelayResponsein interfaceSSU2Payload.PayloadCallback- Parameters:
status- 0 = accept, 1-255 = rejectdata- excludes flag, includes signature
gotRelayIntro
Process a received RelayIntro block.- Specified by:
gotRelayIntroin interfaceSSU2Payload.PayloadCallback- Parameters:
aliceHash- hash of the introducerdata- excludes flag, includes signature
gotPeerTest
Process a received PeerTest block.- Specified by:
gotPeerTestin interfaceSSU2Payload.PayloadCallback- Parameters:
msg- 1-7status- 0 = accept, 1-255 = rejecth- Alice or Charlie hash for msg 2 and 4, null for msg 1, 3, 5-7data- excludes flag, includes signature
gotToken
public void gotToken(long token, long expires) Process a received Token block.- Specified by:
gotTokenin interfaceSSU2Payload.PayloadCallback- Parameters:
token- the session token to attach to the next peer testexpires- token expiration time in milliseconds
gotI2NP
Process a received I2NP block.- Specified by:
gotI2NPin interfaceSSU2Payload.PayloadCallback- Parameters:
msg- the parsed I2NP message
gotFragment
public void gotFragment(byte[] data, int off, int len, long messageId, int frag, boolean isLast) Process a received Fragment block.- Specified by:
gotFragmentin interfaceSSU2Payload.PayloadCallback- Parameters:
data- buffer containing fragment dataoff- offset in datalen- length of data to copymessageId- unique message identifierfrag- fragment number (0-based)isLast- whether this is the last fragment
gotACK
public void gotACK(long ackThru, int acks, byte[] ranges) Process a received ACK block; no-op after destruction.- Specified by:
gotACKin interfaceSSU2Payload.PayloadCallback- Parameters:
ackThru- highest contiguous sequence number acknowledgedacks- number of additional acknowledgments beyond ackThruranges- null if none
gotTermination
public void gotTermination(int reason, long count) Process a received Termination block.- Specified by:
gotTerminationin interfaceSSU2Payload.PayloadCallback- Parameters:
reason- termination reason codecount- in theory could wrap around to negative, but very unlikely
gotPathChallenge
Process a received PathChallenge block; no-op after destruction.- Specified by:
gotPathChallengein interfaceSSU2Payload.PayloadCallback- Parameters:
from- null if unknowndata- the challenge bytes, which must be copied out
gotPathResponse
Process a received PathResponse block; no-op after destruction.- Specified by:
gotPathResponsein interfaceSSU2Payload.PayloadCallback- Parameters:
from- null if unknowndata- the response bytes, which must be copied out
toString