Change:
Allows smaller stateless resets to be sent(as small as 21 bytes) and advises endpoints that want to ensure a stateless reset is not detectable send a larger packet if their chosen CIDs are more than 2 bytes.
I don't understand what this is trying to specify. The stateless reset sender has no idea what CID length the peer has chosen (except for the 20 bytes limit), so I don't see how to guarantee that the Reset exceeds minimum size without allowing for the full 20 bytes. Unless this PR is trying to say that it's OK to go smaller if you're willing to risk it...
It's pretty much "it's OK to go smaller if you are willing to risk stateless reset messages being identifiable", but a little stronger than that. The sender of a stateless reset is now no longer bound by the upper limit on connection ID size. That allows for a smaller packet to be sent and still have it get a stateless reset in response. However, the onus for ensuring that the resulting stateless reset is indistinguishable from regular packets moves to the endpoint that would receive the stateless reset. It has to ensure that it never sends a packet small enough that a stateless reset packet would be too small to appear as valid. For instance, take the case where a client needs at least 8 bytes of connection ID, but the server had no connection ID. Though the client has no real need to send larger packets toward the server, it has to pad outbound packets so that the server, should it be forced to send a stateless reset, wouldn't end up sending a packet that appears to have a 7 byte connection ID (which, assuming an observer knows about the client's constraints, would be easy to identify as a stateless reset).
I find this text to be really unclear. Furthermore, if implementers don't pick up the SHOULD we're going to have detectable stateless resets all over the place. And given the final version of extended connection IDs, we're talking about 2 additional bytes over the draft-20 status quo? I don't find this change to be necessary, though I wouldn't raise a huge stink about it. However, I'd like to consider changing SHOULD to MUST. This seems like a potential security vulnerability. At an absolute minimum, I'll propose an editorial rewrite to make these considerations clearer.
In coming back to this, I can agree with Martin. This is very unclear.
Currently, the spec recommends sending Stateless Reset packets of at least 39 bytes. The number is the minimum packet size when using the maximum connection ID length of 18: type byte: 1 client connection ID: 18 packet number + payload: 4 auth tag: 16 39 = 1 + 18 + 4 + 16. The intention there was to make Stateless Resets harder to distinguish from regular server-to-client traffic on a given QUIC connection. However, when client connection IDs are in use, Stateless Resets are inherently distinguishable from regular traffic because they do not carry the previously-used client connection ID. One might say that they could be confused for a change in connection ID, which is true. But let's assume we just changed from an 18 byte client connection ID to a 4-byte connection ID (which is specifically allowed by the spec), then that new packet is still equally indistinguishable from a Stateless Reset. It is true that a client connection ID length change from 18 to 4 is unlikely, but that's not a problem. We just need it to be possible for this to be a valid packet to observers without keys. So I propose that instead of having a minimum required size for stateless resets of 21 and a recommended minimum of 39, we can just say the minimum required size is 25. The important value here is the minimum non-zero connection ID length, not the maximum connection ID length. At the end of the day, a Stateless Reset will stick out to observers who will notice that the client stops sending on that particular connection. The current value of 39 is harming the protocol by increasing the odds of servers not sending Stateless Resets which will cause timeouts on clients instead of failing fast. This is a tradeoff, and we should strive to avoid timeouts instead of trying to hide a packet that can't be hidden.
This is related to Issue
This does not permit the attacker any knowledge of the client. If a client always selects an 18 byte connection ID, a stateless reset will stand out. The goal is to avoid having the message interfered with in transit. After it gets through and is processed, what happens after doesn't matter.
is also related I believe.
The goal is not to avoid the attacker dropping the packet(I'm not sure what other type of interference is possible here?). If they can do that, they can drop all packets and that's likely even worse. The goal is to ensure the packet can't be reliably identified as a stateless reset, which is a much lower bar. As I stated on , if the client wants to ensure it's reset is always large enough to be indistinguishable, it needs to send a packet size that's one byte larger than the smallest packet it expects to receive. Typically, this is a no-op for the client, so compliance is trivial. No matter what happens, a server may send a stateless reset in response to any QUIC packet that's large enough to be valid, and it's not sensible to try to prevent a server from doing that. Even if the packet is smaller than other packets, it's just odd, not invalid, as David said. If we don't do this, I fear clients will increase their effective minimum packet size substantially, which is a cost everyone has to bear, when a large number of clients will use 0 byte CIDs.
My point is that the packet is invalid, if it is sent to a client that you know uses longer connection IDs. The middlebox can then reliably identify the packet as being a stateless reset. All it needs to know is that that client never uses shorter connection IDs. That's not difficult; we don't assume that this sort of information is a secret.
The only rule is that the CID can't become 0 length, so why is it invalid? If the middlebox can't reliably identify the packet as invalid, it's all a matter of statistics and how much of an anomaly it is. Sure, maybe it's an anomaly for CIDs to go from 18 to 1, but I don't think that's the most likely anomaly on the internet(see below). I think the existing rule is actively harmful in multiple ways, one of which is a possible escalation of the minimum client packet size mentioned above. The more problematic issue is that the goal is to have stateless reset not stick out and be clearly identifiable. If so, we want the widest selection of sizes possible. Given servers are going to want to send stateless resets smaller than the client's packet, a fixed size is going to stick out and the larger the minimum fixed size, the more it's going to stick out. In particular, 40 is enough larger than the typical 'small' server to client packet(ie: ACK) that it's relatively unlikely on a typical connection. If 90%+ of 40 byte payloads are stateless rejects, then we have failed at our goal and I think that's where we're at today. To come back to my previous suggestion, why can't the client enforce this?
It's not generically invalid, it's only invalid in a particular context. And we have to assume that our adversary understands that context better than the endpoint that generates the stateless reset. That's all. To be clear, we don't expressly forbid sending of a smaller stateless reset, only strongly imply that it won't be effective. So I'm struggling to understand what you would concretely do here.
NAME What is this adversary trying to accomplish here? Can you elaborate on threat vector? The number 39 is reducing the reliability of the protocol, what security property does it give us in exchange?
I believe that we wanted to avoid the observer from being able to recognize resets. The idea being that recognition preceded some sort of action. The worst I can imagine here is dropping state prior to the endpoints being ready for that. For instance, forwarding the packet and then dropping NAT bindings immediately, which - if that packet is lost - might leave the recipient with the belief that it still has an active connection when it does not. The point being that we're attempting to avoid facilitation of bad behaviour. Perhaps you can talk about the way in which you perceive reliability being reduced. 39 isn't exactly a very large number, nor is it a hard limit.
I agree with this threat model. We really want to avoid NATs reacting to stateless resets the way they react to TCP RSTs today. However, we've heard from implementors that the majority of QUIC traffic will not use client connection IDs. But there will be an implementation that uses them (either all the time, or at least some of the time, to apply grease to servers to make sure they support them). Let's assume there is a client implementation called CLIENT18 that always uses 18-byte client CIDs. Do you think someone will go out of their way to implement code that detects CLIENT18 traffic, and then installs a rule for those connections only where the detection of a server-to-client packet shorter than 39 bytes will drop the NAT mapping? This sounds about as likely as a NAT implementation that drops packets whose connection IDs are prime numbers... To answer your question on reliability: I think it will be common to have a client establish a connection, send some requests, get the responses, then idle for a few minutes, then after user action, sends another request. Assuming the server uses 8-byte CIDs, this will cause the client to send a packet than can easily be under 39 bytes (assuming a short request). Let's assume the server has restarted during the idle period. It won't recognize the connection ID. If the server decides that this packet is too short to trigger a stateless reset, then the client will timeout causing user-visible delays. For a protocol with such a goal of improving latency, a timeout is a critical failure. The issue here is that the spec doesn't mandate the client to pad its packets, and allows servers to not respond to short packets. Giving both implementations too much leeway is dangerous here. It would be in the spirit of the spec to be more prescriptive. We remove the 39-byte requirement, and tell servers that their stateless resets should be of length in the range . We then tell clients to pad their packets such that .
I could live with that. That is a lot harder to write down, but I think that it might work. I wouldn't make the calculation so complex (just say that the minimum packet size is to account for 1 type byte, 1 data byte, and 16 auth tag bytes plus the connection ID length and the one extra byte we lose for the stateless reset) and I wouldn't tie it to a particular role (stateless reset is supposed to be symmetric, it's just that one direction in particular is more likely by far). We can leave the details to implementations. I was concerned about clients that were also identifiable by means easier than fingerprinting. Say someone who deployed client code in their server cluster, where connection IDs are far more likely as a client, for whom any packet (to a client or server) could be readily identified as a stateless reset by virtue of its size. Profiling by IP address would be easy for someone to do in that case.
What about small ACK-only packets? Would they have to be padded - and what would the avg. cost be of that?
I also agree that not recognizing resets is the goal, but I don't think we're currently achieving that for reasons stated above. And as David pointed out, I think there are allowed behaviors that would not elicit a stateless reset when you'd really like to have one sent. Why maxcid length, not mincid length if we're trying to establish the lower bound on the packet size that could have been sent previously in the connection? Either way, mincid+19 works for me, since I'm mostly concerned about cases with 0, or small fixed CID lengths.
You are right, it's the minimum length. For 0, that means 0.
One calculation error to fix, and some editorial suggestions.

Discussion:
Stateless Reset Token. To entities other than its intended recipient, a stateless reset will <del> appear to be a packet with a short header.  For the packet to appear as valid, the Unpredictable Bits field needs to include at least 198 bits of data (or 25 bytes, less the two fixed bits).  This is intended to allow for a Destination Connection ID of the maximum length permitted, with a minimal packet number, and payload.  The Stateless Reset Token corresponds to the minimum expansion of the </del> <ins> appear to be a packet with a short header.  For the stateless reset to appear as a valid QUIC packet and be smaller than the received packet, the Unpredictable Bits field needs to include at least 46 bits of data (or 6 bytes, less the two fixed bits).  To ensure the stateless reset packet is not smaller than other packets received on the connection, an endpoint SHOULD also ensure the total packet length is at least the minimum chosen CID length plus 22 bytes.  22 bytes allows for 1 type byte, 4 packet number and data bytes, 16 bytes for AEAD expansion, and an extra byte to allow the peer to send a smaller stateless reset than the packet it receives. The Stateless Reset Token corresponds to the minimum expansion of the </ins> packet protection AEAD.  More unpredictable bytes might be necessary if the endpoint could have negotiated a packet protection scheme with a larger minimum AEAD expansion.

close connections when other peers or connections have exhausted limits. <del> Reducing the size of a Stateless Reset below the recommended minimum size of 41 bytes could mean that the packet could reveal to an observer that it is a Stateless Reset.  Conversely, refusing to send a Stateless Reset in response to a small packet might result in Stateless Reset not being useful in detecting cases of broken connections where only very small packets are sent; such failures might only be detected by other means, such as timers. An endpoint can increase the odds that a packet will trigger a Stateless Reset if it cannot be processed by padding it to at least 42 bytes. </del> <ins> Reducing the size of a Stateless Reset below 41 bytes means that the packet could reveal to an observer that it is a Stateless Reset, depending upon the length of the peer's connection IDs.  Conversely, refusing to send a Stateless Reset in response to a small packet might result in Stateless Reset not being useful in detecting cases of broken connections where only very small packets are sent; such failures might only be detected by other means, such as timers. </ins> 11.