diff --git a/i2p2www/spec/proposals/159-ssu2.rst b/i2p2www/spec/proposals/159-ssu2.rst index 7860431ed5b7fa416ecffba1b3bbb4023127207c..97d66a343e98cbaa74459b10e8f0cfbfde2c656a 100644 --- a/i2p2www/spec/proposals/159-ssu2.rst +++ b/i2p2www/spec/proposals/159-ssu2.rst @@ -5,7 +5,7 @@ SSU2 :author: orignal, zlatinb, zzz :created: 2021-09-12 :thread: http://zzz.i2p/topics/2612 - :lastupdated: 2021-10-21 + :lastupdated: 2021-10-22 :status: Open :target: 0.9.55 @@ -2258,6 +2258,11 @@ and Charlie then acts on that request. We have the following goals in improving the security of Relay and Peer Test: +- Charlie should publish enough information about his introducers (Bobs) + in the netdb for Alice to be able to validate the information if necessary. + For example, publishing a router hash for each introducer would + enable Alice, time permitting, to fetch the router info from the netdb. + - Protect against address spoofing or on-path threats that may spoof, alter, forge, or replay requests from Alice to Bob. Bob must ensure that Alice is an actual I2P router and that the @@ -4917,7 +4922,7 @@ Handshake Retransmission Session Request ---------------- -If no Session Created is received: +If no Session Created is received by Alice: Maintain same source and connection IDs and ephemeral key. Increment packet number. Re-encrypt Noise payload as AEAD (packet number) changed. @@ -4929,7 +4934,7 @@ Recommended timeout: 15 seconds total Session Created ---------------- -If no Session Confirmed is received: +If no Session Confirmed is received by Bob: Maintain same source and connection IDs and ephemeral key. Increment packet number. Re-encrypt Noise payload as AEAD (packet number) changed. @@ -4948,17 +4953,31 @@ at 3 and 6 seconds (3 and 9 seconds after first sent). There are several alternatives. All are 1 RTT: -1) Alice assumes Session Confirmed was received, sends data packets immediately, +1) Alice assumes Session Confirmed was received, sends data messages immediately, never retransmit Session Confirmed. Data packets received out-of-order (before Session Confirmed) will be undecryptable, but will get retransmitted. - If Session Confirmed is lost, all sent data packets will be dropped. + If Session Confirmed is lost, all sent data messages will be dropped. -2) As in 1), send data packets immediately, but also retransmit Session Confirmed - until a data packet is received. +2) As in 1), send data messages immediately, but also retransmit Session Confirmed + until a data message is received. 3) We could use IK instead of XK, as it has only two messages in the handshake, but it uses an extra DH (4 instead of 3). +The preferred alternative is option 2). +Alice must retain the information required to retransmit the Session Confirmed message. +Alice should also retransmit all Data messages after the Sesession Confirmed +message is retransmitted. +Bob may retain (queue) the data messages received before the Session Confirmed message. +Neither the header protection keys nor the decryption keys are available +before the Session Confirmed message is received, so Bob does not know +that they are data messages, but that can be presumed. +After the Session Confirmed message is received, Bob is able to +decrypt and process the queued Data messages. +If this is too complex, Bob may just drop the undecryptable Data messages, +as Alice will retransmit them. + + Retry --------- @@ -5087,7 +5106,199 @@ into three different block types, to improve processing efficiency. Congestion Control ==================== -Sequence numbers, acks, backoff, retransmission +Packet numbers, acks, backoff, retransmission, implementation guidance + +General guidance may be found in [RFC-9002]_. + + + +Packet Numbers +-------------- + +In SSU 1, ACKs and NACKs contained I2NP message numbers and fragment bitmasks. +Transmitters tracked the ACK status of outbound messages (and their fragments) +and retransmitted fragments as required. + +In SSU 2, ACKs and NACKs contain packet numbers. +Transmitters must maintain a data structure with a mapping of packet numbers to their contents. +When a packet is ACKed or NACKed, the transmitter must determine what +I2NP messages and fragments were in that packet, to decide what to retransmit. + + +Session Confirmed ACK +------------------------ + +Bob should send an ACK as soon as possible after receiving the Session Confirmed message. +A small delay (no more than 100 ms) is acceptable, since at least one Data message should arrive almost +immediately after the Session Confirmed message, so that the ACK may acknowledge both +the Session Confirmed and the Data message. +This will prevent Bob from having to retransmit the Session Confirmed message. + + +Generating ACKs +-------------------- + +Routers acknowledge all packets they receive and process. However, +only ack-eliciting packets cause an ACK block to be sent within the +maximum ack delay. Packets that are not ack-eliciting are only +acknowledged when an ACK block is sent for other reasons. + +When sending a packet for any reason, an endpoint should attempt to +include an ACK block if one has not been sent recently. Doing so +helps with timely loss detection at the peer. + +In general, frequent feedback from a receiver improves loss and +congestion response, but this has to be balanced against excessive +load generated by a receiver that sends an ACK block in response to +every ack-eliciting packet. The guidance offered below seeks to +strike this balance. + +The following frames are ack-eliciting: + +- I2NP message +- First fragment +- Follow-on fragment +- Session Confirmed message +- Relay? +- Peer Test? +- Others? + +Also: + +- Session Request is implicitly acked by Session Created +- Session Created is implicitly acked by Session Confirmed + + + +Sending ACK Blocks +--------------------- + +Every packet should be acknowledged at least once, and ack-eliciting +packets must be acknowledged at least once within the maximum delay +an endpoint communicated using the max_ack_delay transport parameter. + max_ack_delay declares an explicit contract: an +endpoint promises to never intentionally delay acknowledgments of an +ack-eliciting packet by more than the indicated value. If it does, +any excess accrues to the RTT estimate and could result in spurious +or delayed retransmissions from the peer. A sender uses the +receiver's max_ack_delay value in determining timeouts for timer- +based retransmission. + +An endpoint MUST acknowledge all ack-eliciting handshake +packets immediately +within its advertised max_ack_delay, with the following exception. +Prior to handshake confirmation, an endpoint might not have packet +protection keys for decrypting Handshake, 0-RTT, or 1-RTT packets +when they are received. It might therefore buffer them and +acknowledge them when the requisite keys become available. + +Since packets containing only ACK blocks are not congestion +controlled, an endpoint must not send more than one such packet in +response to receiving an ack-eliciting packet. + +An endpoint must not send a non-ack-eliciting packet in response to a +non-ack-eliciting packet, even if there are packet gaps that precede +the received packet. This avoids an infinite feedback loop of +acknowledgments, which could prevent the connection from ever +becoming idle. Non-ack-eliciting packets are eventually acknowledged +when the endpoint sends an ACK block in response to other events. + +An endpoint that is only sending ACK blocks will not receive +acknowledgments from its peer unless those acknowledgments are +included in packets with ack-eliciting blocks. An endpoint should +send an ACK block with other frames when there are new ack-eliciting +packets to acknowledge. When only non-ack-eliciting packets need to +be acknowledged, an endpoint MAY choose not to send an ACK block with +outgoing blocks until an ack-eliciting packet has been received. + +An endpoint that is only sending non-ack-eliciting packets might +choose to occasionally add an ack-eliciting block to those packets to +ensure that it receives an acknowledgment. In +that case, an endpoint MUST NOT send an ack-eliciting block in all +packets that would otherwise be non-ack-eliciting, to avoid an +infinite feedback loop of acknowledgments. + +In order to assist loss detection at the sender, an endpoint should +generate and send an ACK frame without delay when it receives an ack- +eliciting packet either: + +* when the received packet has a packet number less than another + ack-eliciting packet that has been received, or + +* when the packet has a packet number larger than the highest- + numbered ack-eliciting packet that has been received and there are + missing packets between that packet and this packet. + +Similarly, packets marked with the ECN Congestion Experienced (CE) +codepoint in the IP header SHOULD be acknowledged immediately, to +reduce the peer's response time to congestion events. + +The algorithms are expected to be resilient to +receivers that do not follow the guidance offered above. However, an +implementation should only deviate from these requirements after +careful consideration of the performance implications of a change, +for connections made by the endpoint and for other users of the +network. + + +ACK Frequency +----------------- + +A receiver determines how frequently to send acknowledgments in +response to ack-eliciting packets. This determination involves a +trade-off. + +Endpoints rely on timely acknowledgment to detect loss. +Window-based congestion controllers rely on +acknowledgments to manage their congestion window. In both cases, +delaying acknowledgments can adversely affect performance. + +On the other hand, reducing the frequency of packets that carry only +acknowledgments reduces packet transmission and processing cost at +both endpoints. It can improve connection throughput on severely +asymmetric links and reduce the volume of acknowledgment traffic +using return path capacity; see Section 3 of [RFC-3449]_. + +A receiver should send an ACK block after receiving at least two ack-eliciting packets. +This recommendation is general in nature and +consistent with recommendations for TCP endpoint behavior [RFC-5681]_. +Knowledge of network conditions, knowledge of the peer's congestion +controller, or further research and experimentation might suggest +alternative acknowledgment strategies with better performance +characteristics. + +A receiver may process multiple available packets before determining +whether to send an ACK block in response. + + +Congestion +---------- + +I2P transports do not guarantee in-order delivery of I2NP messages. +Therefore, loss of a Data message containing one or more I2NP messages or fragments +does NOT prevent other I2NP messages from being delivered; +there is no head-of-line blocking. +Implementations should continue to send new messages during the loss recovery +phase if the send window allows it. + + +Retransmission +--------------- + +A sender does not need to retain the full contents of a message, to be retransmitted +identically, although that is allowed. +A sender is encouraged to assemble messages containing up-to-date information +(ACKs, NACKs, and unacknowledged data) every time it sends a message. +A sender should avoid retransmitting information from messages once they are acknowledged. +This includes messages that are acknowledged after being declared lost, +which can happen in the presence of network reordering. + +Window +------- + +TBD. +General guidance may be found in [RFC-9002]_. + @@ -5545,9 +5756,15 @@ References .. [RFC-2104] https://tools.ietf.org/html/rfc2104 +.. [RFC-3449] + https://tools.ietf.org/html/rfc3449 + .. [RFC-3526] https://tools.ietf.org/html/rfc3526 +.. [RFC-5681] + https://tools.ietf.org/html/rfc3681 + .. [RFC-5869] https://tools.ietf.org/html/rfc5869 @@ -5572,6 +5789,9 @@ References .. [RFC-9001] https://datatracker.ietf.org/doc/html/rfc9001 +.. [RFC-9002] + https://datatracker.ietf.org/doc/html/rfc9002 + .. [RouterAddress] {{ ctags_url('RouterAddress') }}