jiebi/CodeConvo huggingface dataset:
Text and pseudocode have been updated.
I just updated the pseudocode as well, since it's quite straightforward.
When the PTO is not armed due to the amplification limit and then a packet is received: URL, it's important to send data for the PN spaces the PTO is armed for(Initial or Handshake) prior to new application data. Typically PTO suggests writing new data instead of retransmitting data which may or may not be lost, but that's not true during the handshake. This is only an issue for the server, since it's caused by enforcing the amplification limits prior to address confirmation. This is most evident when 0-RTT is accepted, but address validation fails, since otherwise a server would not usually have enough data to write to create a problem.
I went and double checked the msquic code , and we always re-enable the loss detection timer when we become "unblocked" by amplification protection logic. I thought this logic was already driven by some statement in the spec. I just went back and found this: Do we need any more than this?
The potential issue is that if the PTO is armed, but should have already expired, it's important to execute it prior to sending any pending data. I'm working on a PR to make this clearer, and we can whether the extra clarification is necessary?
I wonder whether there is something else going on. Amplification or not, 0-RTT packets can only be acknowledged by ACK frames in 1-RTT packets. Those can only be received after the client gets the 1-rtt keys. So implementation should just start a short timer after the handshake completes.
This seems like an editorial change, please confirm. Either way, lets ensure NAME has an opportunity to comment before landing any changes.
ngtcp2 has dedicated code for this situation: URL I feel this is a kind of optimization or implementation techniques.
In response to NAME If the WG establish a consensus on the need for a change a particular fix then this PR can be applied in the AUTH48 with AD approval. I think we need to figure out if not merging the PR until AUTH48 is the best?
It makes it simple to provide the changes to the RFC-editor, but maybe makes it harder for the rest of the community to keep track of the changes if there are no editors copy that contain all agreed things. However, considering the hopefully limited time that may make sense.
We can tag the versions that entered the RFC Editor queue, and then generate a diff against those at AUTH48.
That tag already exists, so we are good.
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 text was a mistake I made when converting from Datagram-Flow-Id to capsules.
Section 4 states that the proxy responds to a CONNECT-UDP request with 2xx and a corresponding registration capsule to indicate end-to-end support of datagrams. If the client sends a REGISTERDATAGRAMCONTEXT capsule, the corresponding capsule from the proxy will be of the same kind, and it will register a new server-generated context ID. So now we would have two context IDs for the same stream, which seems a bit unnecessary. Could we simply omit the step where the proxy sends a registration capsule and simply state that a 2xx response to the CONNECT-UDP request is sufficient indication of end-to-end datagram support?
My reading of the spec is different, URL says So for example, if the client sends a request on stream 4 and then REGISTERDATAGRAMCONTEXT { Context ID (0)}, the server will respond with REGISTERDATAGRAMCONTEXT { Context ID (0)} to confirm that the context is accepted.
That makes sense, I was assuming that the "used in both directions" referred to datagrams. I think my confusion in part came from the same section that says: But sending a registration capsule with an already registered context ID is not a new registration I suppose. Maybe it's good to clarify this a bit in the datagram spec. I'll open a separate issue there.
I agree the draft is a bit ambiguous here.
Indeed, the spec is unclear here, my apologies. I got this wrong when I rewrote the old Datagram-Flow-Id text. The server doesn't need to echo the registration capsule here since the client's registration is bidirectional. NAME we should add text to HTTP Datagrams to clarify what we want to do about echoing registrations, is it required allowed forbidden I'm leaning towards (3) unless we have a use case for communicating the fact that a context is "accepted" and in which case I'd say (2).
Aha! In that case I apologise too. This seems important for interop! Now I remember, I think some people felt registration ack wasn't needed as long as there was a way to reject. And we have that with CLOSEDATAGRAMCONTEXT. So I think (3), modelled as implicit accept and explicit close, sounds good. That cuts down the chatter (and probably simplifies some code in my implementation).
Pretty good. I think that we should at least try to put some MUST-strength language in regarding confidentiality, etc... That makes writing the rest of the security considerations that much easier (you don't have to worry that someone might have ignored your advice and account for it).
Looks good. Further refinements can be done later :)
There is an adequate explanation of the related W3C Push API in the Introduction. Additional references about specific API behavior in Section 9.3 and 9.4 can be removed.
Besides removing extraneous API references, informative references should be added for the separate drafts for optional content encoding and authentication.
Moving to -05. Waiting for a decision on the VAPID call for adoption.
Let's be clearer about what it means to proxy here. Also, since it is the same text, talk about TLS assumptions more directly. This will interact poorly with . Sorry about that NAME
From Vienna chat. A proxy is not a generic HTTP intermediary, and therefore is not subject to the same rules.
From NAME Generic proxies would forward unknown HTTP headers between clients and targets. We should be very clear that oblivious proxies are not generic, and should not be doing things like forwarding unknown headers arbitrarily between client and target, or target and client.
requests. This includes the Via field, the Forwarded field {{?FORWARDED=RFC7239}}, and any similar information. A client does not depend on the proxy using an authenticated and encrypted connection to the oblivious request resource, only that information about the client not be attached to forwarded requests. Obviously, you need encryption on one or the other side of the proxy, right? Probably this document should require it on the inbound side, but I don't see the text that requires it. Did I just miss it?
Yeah, it's only necessary on the inbound side, per the analysis, though the document assumes it's on both sides.
This change clarifies that the signature over ServerDHParams data is a signature over the hash of the client + server hello random random data and the ServerDHParams data. I believe this small regression was introduced in TLS1.2 with the result that the TLS1.2 RFC (and current TLS1.3 draft) does not contain sufficient detail to implement TLS + DHE. All TLS1.2 clients and servers that I have tested do include the hello random data (and omitting it would leave implementations open to replay attacks).
Thanks for the PR. Note that the formal PDU definitions here appear to be correct, so there should be enough information to implement things correctly: I agree it wouldn't hurt to have the explanatory text be clearer. However, in TLS 1.2 we stopped explicitly saying that things were hashed before signing (because we are treating signing as a primitive), so we probably don't want to say "hash". Maybe just say a signature over the random values and the params?
Ah, this explains my confusion. After reading section 7.4.1.4.1, I formed the opposite impression about signing; that hashing and signing are explicitly different primitive operations and may be composed in a variety of ways. But I see how that "digitally-signed" seems to be a reserved term that implies both operations.
I'm not trying to discourage you here. If you were confused, others will probably be as well, so if you have some text that you think would clear this up, it would be welcome.
Thanks! I've updated the PR with an even simpler diff that I think would have made me less confused when I got to it.
more details on encoding application group name, for
Reading the paragraph after "An application group can be named in many ways", I was left a bit confused: Why should it be encoded in the Uri-Query? That'd need coordination among all applications running on that host (for it is interfering with the query argument space that's usually left for the application to use). The common partitioning of applications inside a host is left-to-right in the URI, and that puts it in the very last spot. I think I do see what is meant by the discouragement of using the Uri-Host, but doubt that it'd be immediately obvious to general readers. How I understand Uri-Host to be impractical here is that while the request is sent to a well-defined and named URI, the response is a representation of the same URI with the individual server's IP replaced into the authority component, and if two application groups on the same CoAP group use the same path, then there may be clashes, not on the request-response layer (where the responses are bound to request for a particular host name) but in the client's cache of the responses. (And once one is at the point where application groups in the same CoAP group have a disjunct path set, one can do away with identification altogether and just address the unique path). I don't quite follow how this is not "as intended in RFC7252": It is an identifier for who is being addressed, and as such just part of the URI. (For example, if I define my lights group to be named URL and name the resource , then the host name is exactly the group name, and already needs to be put into the request unless there is known URI aliasing). See also URL on "send a Uri-Host" option, with the caveat that I'm a strong proponent of answer A2. Furthermore, the text seems to imply that virtual hosting is something a server would need to go out of its way to implement. It isn't: The Uri-Host option is critical, and a host needs to make the conscious decision to ignore that option; otherwise it's just as much part of finding the addressed resource as all the other Uri-* options are.
The best practice is something I can get behind, although I suggest using no identifier on the wire (and just the disjunct set of resources) as a byte saving alternative when the administrative effort of ensuring path uniqueness can be afforded.
Thanks; we do need to improve the current text on these aspects. On Uri-Host and your example "URL" where authority component includes the application group: in this group communication example the sending client would normally DNS-resolve "URL" to a particular multicast IP address, then send the CoAP request to this multicast IP address destination, without including any Uri-Host Option. This works as long as you have a unique 1:1 association between application-group and CoAP-group. In case multiple application-groups map to a single CoAP-group, this doesn't work anymore : a client could be e.g. configured to always include the "Uri-Host" Option to indicate the hostname. Still not the preferred approach I would think. Btw I can't follow answer A2 on the CoAP-Faq, unfortunately: formulation is too complex. In some (common?) constrained use cases, the DNS name would not even be configured in the client and the client would just be configured directly with the IPv6 multicast address of the CoAP group to send it to. Then, the application-group would need to be encoded in some way still, e.g. using the Uri-Path Option. Now what our original text tried to suggest is to "misuse" a Uri-Host Option for that. So instead of using an option like: Uri-Path = group123 You would instead use an option: Uri-Host = group123 So this is not a "real" URI hostname but rather a low-level hack to let the client's CoAP stack insert by force an additional option just before sending out the CoAP request. The receiver's CoAP stack would just parse it as the ID of the application-group and not really as a URI-host. Because this gets confusing and potentially messy (proven by the present discussion !) we don't recommend it. So, trying to reiterate if one has configured Group URIs of the form coap://[mcast-ip-address]/resource on the client then by default the Uri-Host Option would get elided. The above mentioned "hack" is to put it back to encode application-group.
This has the issue that the application-group name isn't present in the Group URI. if one has configured Group URIs of the form URL on the client then normally by default the authority gets resolved to some IP multicast address before sending it out, and thus while sending it the Uri-Host Option is NOT included in the CoAP encoding but elided. So the receiving server doesn't see the application-group ID because it's not encoded in the request data. (We assume here that multiple application-groups use the same CoAP-group.) Maybe we should discuss this further; what's the effort here / who ensures it / unique between what and what?
Initial text proposed in above PR! We'll merge it in by tomorrow evening, as an improvement (hopefully). What is not included yet is a statement saying that we don't recommend using the non-Group-URI methods of encoding application group name. To do so we would need to clearly state why that is not recommended; still not clear at this moment what the disadvantages of these are.
While we're renaming these anyway, exportersecret and resumptionsecret are just as descriptive.
exportermainsecret and resumptionmainsecret strike me as not needing an adjective in the middle at all. Perhaps exportersecret and resumptionsecret? For the exporter secret, dropping "main" avoids the acronym collision with the EMS extension, and there are no other secrets associated with exporters, so there's no use in designating this as the main one. For the resumption secret, there is a potential confusion between resumption[main]secret and the derived PSK associated with the ticket (section {#NSTMessage}), but we don't seem to give the latter a name in the first place so I think that's fine. This also gives us nice short KDF labels when we're able to change those: "exporter" and "resumption". (Or perhaps even "export" and "resume" if those don't fit in a hash block.)
I didn't like something about reliability (let's not throw an error when we can't be UNreliable, only when we can't be reliable). I updated the text on ordering a bit, to say that the Property is ignored for the first Message on a Connection, and rephrased it slightly to talk about the receiver-side transport system and the receiving application - before, the text might have talked about a sender-side behavior. I added a TODO DISCUSS comment about per-message Niceness.
Fine with me, maybe fix minor knitThanks, all good now I think.
addresses
In "Connection ID and Rebinding": "Even when encrypted, a scheme could embed the unencrypted length of the Connection ID in the Connection ID itself, instead of remembering it, e.g. by using the first few bits to indicate a certain size of a well-known set of possible sizes with multiple values that indicate the same size but are selected randomly." I almost went and filed an issue against quic-lb to do this instead of just encoding a plaintext length like it does currently. But is this a good recommended practice? ISTM that long headers would provide a bit of a Rosetta Stone for this mapping, making it not particularly effective for the complexity.
The idea was not to conceal the length but to avoid likability by identifying linked connection based on the existence of a certain length field. This might look slightly more random but I guess you also have to change your mapping more time to time. So not sure. I'm fine to remove that half sentence and maybe add a sentence about likability instead...?
Yes, I would prefer deleting the quoted text, as I think it's a solution that adds complexity for little apparent benefit.
Okay, will do that change after your PR has landed.