Original text:
can be mounted using spoofed source addresses.  In determining this limit, servers only count the size of successfully processed packets. <del> Clients MUST ensure that UDP datagrams containing only Initial packets are sized to at least 1200 bytes, adding padding to packets </del>  in the datagram as necessary.  Sending padded datagrams ensures that the server is not overly constrained by the amplification restriction.

Reviewer comments:
I was a bit unsure if the text meant 1200 or 1192 byte payloads. I think this is clearer. by removing the "only"
Not directly related to the change which is editorial, but why is it that 1200 only applies to Initial? Isn't it possible to coalesce Initial with random other packets and thereby work around this limit?
NAME I agree that the wording currently implies if a client bundles a 0-RTT packet with an Initial in a datagram, then it's ok for it to be less than 1200 bytes, which I don't believe is what we want?
NAME NAME I agree with the concern, and have opened (before reading your comments here). I think this PR can be kept an editorial issue while needs to be a design issue.
At the moment, states, quote: "Clients MUST ensure that UDP datagrams containing only Initial packets are sized to at least 1200 bytes, adding padding to packets in the datagram as necessary." I think this is incorrect and that "only" should be dropped, as it excludes a UDP datagram that contains an Initial and a 0-RTT packet. Pointed out by NAME in .
Technically a design change. I think that it should be any packets that contain Initial and don't contain Handshake or 1-RTT packets. At least, that's what I implemented.
I'll note that I think there are other requirements formulated in other sections. Perhaps define a term such a minimal initial datagram size and have the requirement in one place rather than sprinkling 1200 bytes in multiple places where it can be difficult to get the finer points (such as UDP vs QUIC packets and with or without header size). For example section 14 in transport:
NAME What you implemented should be fine. However, Initial + 0-RTT coalesced in a datagram should be padded I believe and I don't think we're clear on that today.
It might be simpler to require every UDP packet that contains an Initial be padded to at least 1200? I'm worried that only requiring that of Initial if there is no Handshake/1-RTT present might be tricky on the receiver: what do I do if I receive a non-padded Initial with Handshake but I can't decrypt the Handshake data?
NAME What we are talking here is a requirement specific to clients, and I am not sure if a client has a chance of sending Initial and Handshake packets at the same time. Quoting of the TLS draft, "a client MUST discard Initial keys when it first sends a Handshake packet." And even if there is a possibility of a client sending Initial and Handshake at the same moment, I do not think requiring the client to pad a packet that contains only an Initial is correct, as coalescing is an optional behavior to the send side. It would mean that clients coalescing the QUIC packets would send a non-padded datagram, while clients not coalescing would send a padded datagram. That seems like an odd behavior.
And yet another issue gets sucked into the wormhole that is the key discard mess. I guess that we will have to make a final determination based on the outcome of that stuff.
On consideration, I think that the requirement is simple and we don't have to stress about interactions with discarding keys. If the packet contains an Initial, it's possible that the Initial packet is the only packet that can be used by a server. Therefore, the datagram should be padded to 1200, regardless of whatever else is included. So we strike the "only" and we're good. See 6cfcbe26385f17072ccd330aea619f65bf3bdcb4.
I wonder - if 0-RTT does not have huge certificates, would it not make sense to permit small packets in this case, provided the auth token validates. But in other cases 1200 bytes must be provided. But since 0-RTT might fail, this could then require a retransmission. Resource constrained devices might be prefer the latter.
NAME Regardless of 0-RTT, for bandwidth constrained deployments, it makes sense for a client to always send a small packet and let the server validate the path. That said, the chartered goal of V1 is to reduce the connection establishment latency, and we have explicitly decided to require clients to send full-sized packets until the path is validated. I do not think we should revisit that design. Maybe we can in v2.
I do not believe that this is necessarily correct. The reason is that we have not yet nailed down Initial key discard and in at least one version, an Initial ACK would appear in the client's second flight, but that need not be padded.
I think the specification should mandate padding of server initial packets as well. When I was traveling a couple weeks ago, I was on a network where, when using IPv6, it allowed 1200-byte UDP packets through from client to server but blackholed them from server to client. Since our implementation pads initials in both directions, we were able to detect this failure during the handshake and fall back to TCP/TLS. If the server didn't pad its initials, we would have succeeded at the handshake but never gotten an HTTP response.
This definitely seems like a design issue. The purpose of the padding rule is solely to limit amplification, not to establish a minimum MTU. If you want some sort of MTU rule, that should be discussed separately.
This issue is marked as design. Are you suggesting I should open a separate one?
NAME I believe it is dual purpose: From the current transport draft: >The payload of a UDP datagram carrying the first Initial packet MUST be expanded to at least 1200 bytes, by adding PADDING frames to the Initial packet and/or by coalescing the Initial packet (see Section 12.2). Sending a UDP datagram of this size ensures that the network path supports a reasonable Maximum Transmission Unit (MTU), and helps reduce the amplitude of amplification attacks caused by server responses toward an unverified client address; see Section 8.
Yeah, that's dicta as far as I am concerned. I don't think we ever had consensus that we were going to enforce MTU here.
The insight I had here was this: If you are sending Initial, it is possible that this is the only packet in the datagram that can be processed by your peer. If that is the case, then a client needs to ensure that it pads the datagram as though no other packets were present. You can infer from the fact that you have Handshake keys that the server is able to process Handshake packets, and then extend that to say that if you include Handshake packets then the server won't need padding. But then you can extend that inference to saying that there is no need to send any Initial packets (as the current draft does; currently, you are not required to keep Initial keys once you are sending with Handshake keys). Either way, I figure that it is better to keep things simple and say "if Initial, pad". In those cases where padding ends up being excessive, it's only excessive for a short while.
I don't know where you get this from. It's total datagram size that matters, not the contents of the rest of the datagram (which is why the neqo padding strategy works). Anyway, the algorithm you propose seems fine, but it's not necessary, and therefore there's no need to specify it in the spec.
This was my thought too.
I'm not seeing a conflict between these statements. If the packet contains an Initial, the total datagram size must be at least 1200 bytes. You can achieve this by padding any packet in the payload; I don't think anyone is advocating for requiring the padding be in a particular spot.
I don't understand what "pads the datagram as though no other packets were present" is supposed to mean, then. The way neqo does this is that it puts the packets in the datagram and then pads the rest, without any regard to what keys the server might have.
Imprecise wording on my part. "pads the datagram as though no other packets were present" might be better as "as though no other packets can be processed by the server". Let's keep in mind that the proposed changes is just striking "only" in "Clients MUST ensure that UDP datagrams containing Initial packets have UDP payloads of at least 1200 bytes, [...]". I agree that this will result in larger packets than are ideal in a couple of cases. But the ACK-only Initial packets a client sent are most likely coalesced with other packets outside of cases where the padding is genuinely required.
I'm sorry, but I still don't see what benefit this change provides. Perhaps this would be easier next week.
The change makes it clear that if you send Initial+0-RTT then you should still pad to 1200. That's all. Previously, you would not have been required to pad, which would have been bad. Most of the debate and discussion is about the knock-on consequences of applying the broader rule, which I don't think are that important. And yes, the whole "when do you discard Initial keys" thing does confound things a little.
Discussed in Cupertino. The word "only" is to be removed from the respective sentence. Moving to Editorial.
This is much clearer, thanks!

Revised text:
can be mounted using spoofed source addresses.  In determining this limit, servers only count the size of successfully processed packets.  <ins> Clients MUST ensure that UDP datagrams containing Initial packets have UDP payloads of at least 1200 bytes, adding padding to packets </ins> in the datagram as necessary.  Sending padded datagrams ensures that the server is not overly constrained by the amplification restriction.