jiebi/CodeConvo huggingface dataset:
Code change:
All comparisons of text strings are performed byte-by-byte (and therefore necessarily case-sensitive). <ins> Where arithmetic is used, this specification uses the notation familiar from the programming language C, except that the operator "**" stands for exponentiation. </ins> 4. Each SenML Pack carries a single array that represents a set of

Related discussion:
text: One possible way to address the problem with positive relative times
NAME Fixed
Looks like two of you are still working details of phrasing but I like where it is going and all looks about right to me.
Code change:
However, QUIC DATAGRAM frames do not provide a means to demultiplex application contexts.  This document describes how to use QUIC DATAGRAM frames when the application protocol running over QUIC is <del> HTTP/3 H3.  It defines logical flows identified by a non-negative integer that are present at the start of the DATAGRAM frame payload. Flows are associated with HTTP messages using the Datagram-Flow-Id header field, allowing endpoints to match unreliable DATAGRAMS frames to the HTTP messages that they are related to. This design mimics the use of Stream Types in HTTP/3, which provide a demultiplexing identifier at the start of each unidirectional stream. </del> <ins> HTTP/3 H3.  It associates datagrams with client-initiated bidirectional streams and defines an optional additional demultiplexing layer. </ins> Discussion of this work is encouraged to happen on the MASQUE IETF mailing list (masque@ietf.org [2]) or on the GitHub repository which

Related discussion:
text: To me it seems like header is sufficient, because the context IDs are end-to-end, and should not affect intermediaries, making the header a natural place to put it. I think having the context ID be the default behavior and the header is to opt-out is the right decision if we were to allow removing it.
This is a bit of a bike-shed, but why would it default to having context-IDs instead of not having them?
I think the second option "Negotiate the presence of context IDs using an HTTP header" is the best personally. In terms of: "Context IDs would still be mandatory to implement on servers because the client might send that header", I assume server in this context is the final application server, not a proxy? Even so, I'd argue it's applications which decide if they need this functionality, so if a server only implemented one application and it didn't use Context-IDs, then I don't see why it would need to implement it.
Ian, in your comment, are you talking about an intermediary when you say "proxy"? If so, then an intermediary need not implement anything based on the payload of than H3 DATAGRAM, it only has to pass the data along. That may be worth a clarification.
Having context ID optional has a nice future-proof property - other uses of datagrams in HTTP/3 can decide if they want the second layer or not. I wouldn't even state it as application needing multiplexing or not. Other applications might find it very useful to include a second ((third, fourth, fifth) layer of frame header. I think its fine for us to state as much in this in the spec, while also defining an explicit second layer for multiplexing.
Yes, by proxy I meant intermediary. And I agree about what intermediaries need to do, I just wanted to ensure I understood what server meant when David used it above. Yup, whenever all this gets written up, we can make it clear that intermediaries can ignore much of this.
The method defines the semantics of datagrams for a particular request, thus I think the third option makes most sense.
Code change:
However, QUIC DATAGRAM frames do not provide a means to demultiplex application contexts.  This document describes how to use QUIC DATAGRAM frames when the application protocol running over QUIC is <del> HTTP/3 H3.  It defines logical flows identified by a non-negative integer that are present at the start of the DATAGRAM frame payload. Flows are associated with HTTP messages using the Datagram-Flow-Id header field, allowing endpoints to match unreliable DATAGRAMS frames to the HTTP messages that they are related to. This design mimics the use of Stream Types in HTTP/3, which provide a demultiplexing identifier at the start of each unidirectional stream. </del> <ins> HTTP/3 H3.  It associates datagrams with client-initiated bidirectional streams and defines an optional additional demultiplexing layer. </ins> Discussion of this work is encouraged to happen on the MASQUE IETF mailing list (masque@ietf.org [2]) or on the GitHub repository which

Related discussion:
text: I don't see a point in using explicit negotiation, since in the two cases I can think of the top of the head, the answer is always clear from the method (CONNECT-IP seems to always want context IDs, WebTransport does not ever want context IDs). If some method starts out without context, but wants to add context later, it can add its own negotiation.
One set of use cases for which the method approach(3) is best are those where there are multiple context IDs but they're predefined by the method and don't need negotiation. My strawman is WebRTC.
During the 2021-04 MASQUE Interim, we discussed multiple options for registering context IDs. Without going into the specific of the encoding, there are two broad classes of solutions: "Header" design Once-at-setup registration This happens during the HTTP request/response Simplest solution is to use an HTTP header such as (encoding TBD) Example use-case: CONNECT-UDP without extensions "Message" design Mid-stream registration This can happen at any point during the lifetime of the request stream This would involve some sort of "register" message (encoding TBD, see separate issue) Example use-case: CONNECT-IP on-the-fly compression (this can't be done at tunnel setup time because the bits top be compressed aren't always known at that time) It's possible to implement once-at-setup registration using the Message design, but it isn't possible to implement mid-stream registration. Therefore I think we should go with the Message design. It would also be possible to implement both but I don't think that provides much value.
I'd like to here some more from the WebTransport use case on the issue. My understanding is that the Requests are used to create WebTransport sessions and that creation of datagram flows(contexts) could be a lot more ad-hoc / server generated after the request phase, when compared to the CONNECT-UDP case. Cc NAME
Personally, I'd vote for either "message" or "message + header" (a la priorities), but not just "header". Mid-stream annotation of context/flow/etc is quite useful.
I prefer "Message" only, since the dynamic use case seems like a fairly compelling use of sub-flows(contexts?).
Code change:
However, QUIC DATAGRAM frames do not provide a means to demultiplex application contexts.  This document describes how to use QUIC DATAGRAM frames when the application protocol running over QUIC is <del> HTTP/3 H3.  It defines logical flows identified by a non-negative integer that are present at the start of the DATAGRAM frame payload. Flows are associated with HTTP messages using the Datagram-Flow-Id header field, allowing endpoints to match unreliable DATAGRAMS frames to the HTTP messages that they are related to. This design mimics the use of Stream Types in HTTP/3, which provide a demultiplexing identifier at the start of each unidirectional stream. </del> <ins> HTTP/3 H3.  It associates datagrams with client-initiated bidirectional streams and defines an optional additional demultiplexing layer. </ins> Discussion of this work is encouraged to happen on the MASQUE IETF mailing list (masque@ietf.org [2]) or on the GitHub repository which

Related discussion:
text: 2) Can the receiver of a flow-id assignment use that same flow-id when sending datagrams, or could this mean something completely different? I think the answer to (1) is "yes, it can tell me to stop" (i.e. it is negotiated while allowing speculative sending). For (2), I lean toward bidirectional, but not strongly. There are plenty of codepoints, so it seems wasteful for each endpoint to define the same semantic explicitly.
NAME the intent of this issue wan't to conflate those two things. This issue is about scope. For consent, see issue .
Conceptually, I like unidirectional better. I tell the peer that when I send with context-ID=X, it has a given semantic. For bidirectional the sender is saying both that and that if the peer sends on that ID the original sender will interpret with the same semantic. That might not even make sense. Is it possible to associate datagrams with a unidirectional stream (push?). If so, does allowing for bidirectional context imply that even though the receiver cannot send frames on the stream, it can send datagrams? Every negotiation does run the risk of loss/reordering resulting in a drop or buffering event at the receiver. The appeal of bidirectional is that it removes half of this risk in the cases where the bidirectionality is used.
To second NAME I would also prefer bidirectional without support for half-close. Given you can always not send something in one direction, and there's none of the overhead of streams(ie: flow control, etc) I can't see any benefits of unidirectional over bidirectional in this case. Associating h3-datagrams with a server push seems like unnecessary complexity to me, but you're right that it should be clarified.
During the 2021-04 MASQUE Interim, we discussed a design proposal from NAME to replace the one-layer flow ID design with a two-layer design. This design replaces the flow ID with two numbers: a stream ID and a context ID.
Code change:
However, QUIC DATAGRAM frames do not provide a means to demultiplex application contexts.  This document describes how to use QUIC DATAGRAM frames when the application protocol running over QUIC is <del> HTTP/3 H3.  It defines logical flows identified by a non-negative integer that are present at the start of the DATAGRAM frame payload. Flows are associated with HTTP messages using the Datagram-Flow-Id header field, allowing endpoints to match unreliable DATAGRAMS frames to the HTTP messages that they are related to. This design mimics the use of Stream Types in HTTP/3, which provide a demultiplexing identifier at the start of each unidirectional stream. </del> <ins> HTTP/3 H3.  It associates datagrams with client-initiated bidirectional streams and defines an optional additional demultiplexing layer. </ins> Discussion of this work is encouraged to happen on the MASQUE IETF mailing list (masque@ietf.org [2]) or on the GitHub repository which

Related discussion:
text: The contents of the QUIC DATAGRAM frame would now look like: While the flow ID in the draft was per-hop, the proposal has better separation: the stream ID is per-hop, it maps to an HTTP request the context ID is end-to-end, it maps to context information inside that request Intermediaries now only look at stream IDs and can be blissfully ignorant of context IDs. In the room at the 2021-04 MASQUE Interim, multiple participants spoke in support of this design and no one raised objections. This issue exists to ensure that we have consensus on this change - please speak up if you disagree.
I am fine with the 2-layer design for CONNECT-UDP, but I am not sure if the second identifier should be in H3 DATAGRAM or should be specific to CONNECT-UDP. As I indicated to the list, webtrans and httpbis might weigh in on this with broader consideration of other use cases.
Hi NAME the topic of the optionality of context IDs is discussed in issue .
I think this is a good design, because it minimizes the core functionality of the draft, but avoids every application that needs multiple dynamically created sub-flows from re-inventing a different mechanism. Nit: I would not call this a 'Frame', since it's not an HTTP(TLV) frame.
I think this is a good change. Thanks! There are some things that I think we should still discuss, but we shouldn't hold up this change on those details.
Code change:
multiple layers of derivation or resolution, such as DNS service resolution and DNS hostname resolution. <ins> For example, if the application has indicated both a preference for WiFi over LTE and for a feature only available in SCTP, branches will be first sorted accord to path selection, with WiFi at the top. Then, branches with SCTP will be sorted to the top within their subtree according to the properties influencing protocol selection. However, if the implementation has cached the information that SCTP is not available on the path over WiFi, there is no SCTP node in the WiFi subtree.  Here, the path over WiFi will be tried first, and, if connection establishment succeeds, TCP will be used.  So the Selection Property of preferring WiFi takes precedence over the Property that led to a preference for SCTP. </ins> 4.3. Implementations should sort the branches of the tree of connection

Related discussion:
text: What's bad about having more information available that can guide the selection process?
NAME the problem is that the Connection properties are not expressed in a way suitable for selection. If they should also be used for Selection they would have to be reworked to be of type Preference. Otherwise I do not know what they mean for selection. What does it mean if I pick say a particular connection group transmission scheduler? Is it required or preferred? Most connection properties also do not look very useful to me for selection so in case there are some we need I think it would be simpler to just define a matching selection property.
NAME we're only discussing whether it's allowed to use them as additional input or not. I agree, some (like the scheduler choice) don't seem useful, but some do... generally we may not have good guidance on how they should be used by an implementation, but giving the system freedom to use as many inputs as possible is probably a good thing. Regarding the type, require/prefer//ignore/avoid/prohibit obviously works fine for a "wishlist" of boolean character: having something, or not having it. The selection properties are generally like that - except "Interface Instance or Type" and "Provisioning Domain Instance or Type" which are, well... wishlist-collections. Consider the capacity profile. Surely configuring this early can be useful input - e.g. if someone picks low latency / interactive, you may even want to put this traffic on a specific network interface! But if you'd want to make a copy of the capacity profile as a "proper" selection property, how would you do it? Apply require/prefer/ignore/avoid/prohibit for each of its values? Then I could say "prefer" low latency/non-interactive but "avoid" low latency/non-interactive, which would surely be odd. Apply the qualifier to the whole thing? Then it's about, e.g. "avoiding" to use a capacity profile at all. That's odd as well. I think it's in the nature of the current selection properties that they merely say "I want to be able to do this, and this is how important it is to me", which is different from configuring something. That's also why, as written, they simply wouldn't work for later connection configuration.
Code change:
multiple layers of derivation or resolution, such as DNS service resolution and DNS hostname resolution. <ins> For example, if the application has indicated both a preference for WiFi over LTE and for a feature only available in SCTP, branches will be first sorted accord to path selection, with WiFi at the top. Then, branches with SCTP will be sorted to the top within their subtree according to the properties influencing protocol selection. However, if the implementation has cached the information that SCTP is not available on the path over WiFi, there is no SCTP node in the WiFi subtree.  Here, the path over WiFi will be tried first, and, if connection establishment succeeds, TCP will be used.  So the Selection Property of preferring WiFi takes precedence over the Property that led to a preference for SCTP. </ins> 4.3. Implementations should sort the branches of the tree of connection

Related discussion:
text: Connection properties really are about configuring something, but I still say that being able to use them as early input is good. I agree that the implementation isn't super clear as they don't come with a require/prefer/... etc. qualifier, but then we just offer some freedom to implementers.
NAME I just pushed a commit that updates the selection and connection properties text, removing "connection" almost everywhere, but adding a disclaimer in the beginning that says that connection properties should be configured as early as possible because they can influence decisions made by the implementation, and "In the remainder of this document, we only refer to Selection Properties because they are the more typical case." Frankly I'm not sure this is better... but it does remove most of the "selection and connection" double mentions that you pointed out.
Fixed up branch building and resolved merge conflicts. I'll merge this in later today before the posting deadline.
Cool thanks! Sorry if I messed something up
As discussed in
Thank you for updating this – looks good! just needs s/send-params/msg-properties/ and merging
Code change:
First four (4) octets of the SHA-256 message digest RFC6234 of the ESNIKeys structure starting from the first octet of "keys" to the <del> end of the stucture. </del> <ins> end of the structure. </ins> The list of keys which can be used by the client to encrypt the SNI.  Every key being listed MUST belong to a different group. The length to pad the ServerNameList value to prior to encryption. This value SHOULD be set to the largest ServerNameList the server <del> expects to support rounded up the nearest multiple of 16. [[OPEN ISSUE: An alternative to padding is to instead send a hash of the server name.  This would be fixed-length, but have the disadvantage that the server has to retain a table of all the server names it supports, and will not work if the mapping between the client-facing server and hidden server uses wildcards.]] </del> <ins> expects to support rounded up the nearest multiple of 16.  If the server supports wildcard names, it SHOULD set this value to 256. </ins> The moment when the keys become valid for use.  The value is represented as seconds from 00:00:00 UTC on Jan 1 1970, not

Related discussion:
text: Current text says: the "encryptedservername" extension. However, I am not sure if this is the desired behavior. I would rather suggest encrypting even when the hostname exceeds the padded_length. Having some protection is better than none. The issue is that in certain deployments it is impossible to guess what the maximum length of the hostname will be. Consider . It uses a wildcard certificate. Anybody can add a new hostname of any length by creating a new Github account (it might be true that Github some limitation on the length, but that does not necessarily mean that Github shares the maximum length information with the fronting CDN, assuming that it uses a CDN).
I have filed that fixes another issue (it's just a clarification of an open issue) related to wildcard delegation.
Technically, it is possible to guess the maximum length of the hostname, as that maximum textual representation length is defined as 253 bytes per RFC 1034.
Yes. So the question is if a CDN that has a wildcard mapping needs to set to 253 (since current text is a MUST NOT for sending a server name longer than the paddedlength), or if we should introduce a different rule.
How about something like: padded_length : The length to pad the ServerNameList value to prior to encryption. This value SHOULD be set to the largest ServerNameList the fronting server expects to support rounded up the nearest multiple of 16. If the fronting server supports wildcard names, it SHOULD set this value to 256.
NAME Thank you for the suggestion. I was feeling uneasy (and am still feeling a bit) about requiring the client to send an ESNI extension as large as ~300 bytes, assuming that CDN's would have at least one wildcard mappings. But it's about the first packet sent from the client, and we typically have enough room even when 0-RTT data is involved. So I think that we can live with that.
To be
Thank you for working on this! LGTM aside from the two comments shown below.Sorry, I missed the padding thing, so you'll need to adjust
Code change:
Tree hash: The root hash of the above ratchet tree <del> Confirmed transcript hash: the zero-length octet string </del> <ins> Confirmed transcript hash: The zero-length octet string </ins> <del> Interim transcript hash: the zero-length octet string </del> <ins> Interim transcript hash: The zero-length octet string </ins> <del> Init secret: a fresh random value of size "KDF.Nh" </del> <ins> Init secret: A fresh random value of size "KDF.Nh" Extensions: Any values of the creator's choosing </ins> For each member, construct an Add proposal from the KeyPackage for that member (see add)

Related discussion:
text: This PR adds a RequiredCapabilities extension that allows the members of a group to impose a requirement that new joiners support certain capabilities. The extension is carried in the GroupContext and verified at Add time (including on external commits). In the interim 2021-10-04, we briefly discussed whether this mechanism needed to be included in the core protocol. Because of its interactions with Add and GroupContextExtensions proposals, it seems worth having in the main protocol.
s currently have two usages in the spec: Pre-published key packages that you can download and put in a leaf when adding a new member leaf node content that you update when doing a full Currently, things have been designed to use only one structure for both uses, leading to some weirdness such as: and are useful in the usage 1, but are parameters of the group in usage 2. is a good name in usage 1, but would better be named in usage 2. some data is important in usage 2 and have no meaning in usage 1, hence they were designed as "mandatory-when-updating extensions" (such as , and we were also discussing about adding the in to help prevent cross-group attacks) How about using different structures for these? // Essentially identical to KeyPackage struct { ProtocolVersion version; CipherSuite ciphersuite; HPKEPublicKey hpkeinitkey; opaque endpointid; Credential credential; Extension extensions; opaque signature; } PrePublishedKeyPackage; struct { HPKEPublicKey hpkekey; opaque endpointid; Credential credential; opaque parenthash; opaque groupid; Extension extensions; opaque signature; } LeafNodeContent; enum { reserved(0), prepublishedkeypackage(1), leafnodecontent(2), (255) } LeafNodeType; struct LeafNode { // This is not included in the signature, but with the "unambiguous signature" PR that's not a problem LeafNodeType type; select(URL) { case prepublishedkeypackage: PrePublishedKeyPackage data; case leafnode_content: LeafNodeContent data; } } What would you think about refactoring like this?
If we're doing this, I'd suggest including a dedicated public key to encrypt Welcome messages to for the . NAME suggested this at some point.