I2PSession -> MessageHandler -> PacketHandler -> ConnectionPacketHandler -> MessageInputStream
One of these is instantiated per-Destination (i.e. per-ConnectionManager, not per-Connection). It doesn't store any state.
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final ByteCacheByte cache for packet buffers.private final I2PAppContextApplication context.private final LogClass logger.private intMessages received with a payload size already seen in this connectionprivate intSample counters for the per-packet size stats (one per call site).(package private) static final StringImmediate ACK delay in ms, applied as min(this, rtt/8) so it can only ever delay an immediate ACK by a fraction of the measured RTT.private static final long[]Period for rates.private static final intRecord every Nth receive-size stat sample.Constructor Summary
ConstructorsConstructorDescriptionConnectionPacketHandler(I2PAppContext context) Create a new ConnectionPacketHandler.Method Summary
Modifier and TypeMethodDescriptionprivate booleanack(Connection con, long ackThrough, long[] nacks, Packet packet, boolean isNew, boolean choke) Process the acks in a received packet, and adjust our window and RTT.private booleanadjustWindow(Connection con, boolean isNew, long sequenceNum, int numResends, int acked, boolean choke) Adjust the congestion window based on ACKs received.(package private) static longcaGrowthCredit(long accum, int effAcked, int caFactor, int windowSize) Credit increment for the deterministic congestion-avoidance ratchet.(package private) static intcaWindowIncrements(long accum) Whole-packet increments harvested from the fixed-point accumulator.(package private) static longcaWindowRemainder(long accum) Fractional remainder after harvesting whole increments; carries over into the next ACK event.static intMaximum slow start window size.(package private) voidreceivePacket(Packet packet, Connection con) Takes ownership of the packet and calls packet.releasePayload() unless it is passed to the MessageInputStream.(package private) static voidRegister the live stream RTT and send-window stats.(package private) static booleanshouldRemainChoked(Connection con, long seqNum, int payloadSize) Determine if a packet should keep the connection choked.(package private) static booleanshouldSampleLiveStreamStats(int receiveMsgCount) Whether this received message is the one that samples the receive-side size stat and, from it, the live stream RTT and send window.private booleanverifyPacket(Packet packet, Connection con) Make sure this packet is ok and that we can continue processing its data.private voidverifyReset(Packet packet, Connection con) Make sure this RST packet is valid, and if it is, act on it.private voidverifySignature(Packet packet, Connection con) Verify the signature if necessary.
Field Details
_context
Application context._log
Class logger._cache
Byte cache for packet buffers.TELEMETRY_SAMPLE_PERIOD
private static final int TELEMETRY_SAMPLE_PERIODRecord every Nth receive-size stat sample. Per-packet RateStat updates lock each period's Rate; these size stats are display-only telemetry, so sampling the aggregate (scaling the recorded value by the period) preserves the graph with a fraction of the monitor traffic.- See Also:
_receiveMsgSizeCnt
private int _receiveMsgSizeCntSample counters for the per-packet size stats (one per call site)._receiveDupMsgSizeCnt
private int _receiveDupMsgSizeCntMessages received with a payload size already seen in this connectionPROP_IMMEDIATE_ACK_DELAY
Immediate ACK delay in ms, applied as min(this, rtt/8) so it can only ever delay an immediate ACK by a fraction of the measured RTT.- See Also:
RATES
private static final long[] RATESPeriod for rates.
Constructor Details
ConnectionPacketHandler
Create a new ConnectionPacketHandler.- Parameters:
context- the I2P application context
Method Details
registerLiveStreamStats
Register the live stream RTT and send-window stats.Separated from the constructor so a test can register against a fresh
StatManagerwithout building a whole handler — the same shape asConnectionManager.registerRtxRatioStats(StatManager).Both are
createRequiredRateStatbecause StatManager silently discards data for a name it was never told about. That failure mode is invisible from the console: the stat reads "not present" rather than wrong, which is howtransport.banlistOnUsupportedSigTypesat at zero through every signature-type banlisting.- Parameters:
sm- stat manager to register with, non-null
shouldSampleLiveStreamStats
static boolean shouldSampleLiveStreamStats(int receiveMsgCount) Whether this received message is the one that samples the receive-side size stat and, from it, the live stream RTT and send window.One predicate for all three, because the live RTT and window are deliberately written inside the same block as the existing size sample: the cost stays two extra stat writes per sampled message rather than two per packet. Sharing the predicate is what stops the cadences drifting apart later — the mask alone would let a change to one silently leave the other per-packet.
Pure predicate — no state, no router, safe for unit tests.
- Parameters:
receiveMsgCount- monotonically increasing count of messages this handler has accepted, 1-based- Returns:
- true when this message is a sampling point
getMaxSlowStartWindow
Maximum slow start window size. Tunable viai2p.streaming.maxSlowStartWindow(default: 32).- Parameters:
ctx- the I2P application context, unused by this static lookup- Returns:
- the max slow start window
receivePacket
Takes ownership of the packet and calls packet.releasePayload() unless it is passed to the MessageInputStream.- Parameters:
packet- the received packetcon- the connection the packet belongs to- Throws:
I2PException- if the packet fails verification
ack
private boolean ack(Connection con, long ackThrough, long[] nacks, Packet packet, boolean isNew, boolean choke) Process the acks in a received packet, and adjust our window and RTT.- Parameters:
con- the connection whose window and RTT are adjusted; may be nullackThrough- the highest ACKed sequence numbernacks- the NACKed sequence numbers, may be nullpacket- the received packetisNew- was it a new packet? false for ack-onlychoke- did we get a choke in the packet?- Returns:
- true if congested
adjustWindow
private boolean adjustWindow(Connection con, boolean isNew, long sequenceNum, int numResends, int acked, boolean choke) Adjust the congestion window based on ACKs received. This either does nothing or increases the window; it never decreases it. Decreasing is done inConnection.ResendPacketEvent.retransmit().- Parameters:
con- the connection whose window is adjustedisNew- was it a new packet? false for ack-onlysequenceNum- 0 for ack-onlynumResends- number of resent packets in this ACKacked- number of packets ACKedchoke- did we get a choke in the packet?- Returns:
- true if congested
caGrowthCredit
static long caGrowthCredit(long accum, int effAcked, int caFactor, int windowSize) Credit increment for the deterministic congestion-avoidance ratchet. Accumulated in 16.16 fixed-point; each whole unit corresponds to one packet-in-flight increment on the congestion window.The expected value equals
effAcked / (caFactor * windowSize), which is the probability that the old random gate would have incremented.- Parameters:
accum- the 16.16 fixed-point accumulator so fareffAcked- effective number of packets ACKed this roundcaFactor- congestion-avoidance growth divisorwindowSize- current congestion window- Returns:
- the accumulator including this round's credit
caWindowIncrements
static int caWindowIncrements(long accum) Whole-packet increments harvested from the fixed-point accumulator.- Parameters:
accum- the fixed-point credit accumulated so far- Returns:
- number of whole window increments
caWindowRemainder
static long caWindowRemainder(long accum) Fractional remainder after harvesting whole increments; carries over into the next ACK event.- Parameters:
accum- the fixed-point credit accumulated so far- Returns:
- fractional remainder in [0, 1048575]
verifyPacket
Make sure this packet is ok and that we can continue processing its data.SIDE EFFECT: Sets the SendStreamId and RemotePeer for the con, using the packet's ReceiveStreamId and OptionalFrom, If this is a SYN packet and the con's SendStreamId is not set.
- Parameters:
packet- the incoming packet to verifycon- the connection the packet is being processed on- Returns:
- true if the packet is ok for this connection, false if we shouldn't continue processing.
- Throws:
I2PException- if the packet is from the wrong destination, or a required signature is missing or forged
verifyReset
Make sure this RST packet is valid, and if it is, act on it. The destination is verified against the connection's own remote peer, so a reset arriving on an established stream is checked against the peer we actually negotiated with, not against a FROM field in the packet.- Parameters:
packet- the RST packet to validate and act oncon- non-null
verifySignature
Verify the signature if necessary.- Parameters:
packet- the packet whose signature is checkedcon- the connection the packet arrived on; supplies the remote peer and key- Throws:
I2PException- if the signature was necessary and it was invalid
shouldRemainChoked
Determine if a packet should keep the connection choked. Used for testing the unchoking decision logic.- Parameters:
con- the connection whose choked state is being decidedseqNum- the packet sequence numberpayloadSize- the packet payload size- Returns:
- true if the connection should remain choked