Question: For cases where the device is not specifically configured with a way to find an RD, the network may want to provide a suitable default. <del> If the address configuration of the network is performed via SLAAC, this is provided by the RDAO option rdao. </del> <ins> The IPv6 Neighbor Discovery option RDAO rdao can do that. </ins> <del> If the address configuration of the network is performed via DHCP, this could be provided via a DHCP option (no such option is defined at the time of writing). </del> <ins> When DHCP is in use, this could be provided via a DHCP option (no such option is defined at the time of writing). </ins> Finally, if neither the device nor the network offers any specific configuration, the device may want to employ heuristics to find a

See-Also: URL This is quite literally from my notes on URL A bit of uncertainty remains whether this change should be two-sided. Should the line above say "When SLAAC is in use," (or "When ND is in use,"?) as well? Can RA options be used in presence of DHCP or static address configuration?
Updated to a more plain and not SLAAC related statement about the RDAO as per last interim. Thank you for the work put into this document. As you can noticed, I have cleared my 2 DISCUSS points (kept below for archive) thank you also for replying to my comments over email. BTW, I appreciated the use of ASCII art to represent an entity-relationship diagram ! I hope that this helps to improve the document, -- Section 4.1 -- It will be trivial to fix, in IPv6 address configuration (SLAAC vs. DHCP) is orthogonal to DHCP 'other-information'. E.g., even if address is configured via SLAAC, DHCPv6 other-information can be used to configure the Recursive DNS Server (or possibly the RD). -- Section 4.1.1 -- Another trivial DISCUSS to fix: in which message is this RDAO sent ? I guess unicast Router Advertisement but this MUST be specified. In general, I wonder how much interactions and exchanges of ideas have happened in the long history of this document with the DNSSD (DNS Service Discovery) Working Group that has very similar constraints (sleeping nodes) and same objectives. -- Section 2 -- To be honest: I am not too much an APP person; therefore, I was surprised to see "source address (URI)" used to identify the "anchor="... I do not mind too much the use of "destination address (URI)" as it is really a destination but the anchor does not appear to me as a "source address". Is it common terminology ? If so, then ignore my COMMENT, else I suggest to change to "destination URI" and simply "anchor" ? -- Section 3.3 -- Should the lifetime be specified in seconds at first use in the text? -- Section 3.6 -- Is the use of "M2M" still current? I would suggest to use the word "IoT" esp when 6LBR (assuming it is 6LO Border Router) is cited later.


Question: For cases where the device is not specifically configured with a way to find an RD, the network may want to provide a suitable default. <del> If the address configuration of the network is performed via SLAAC, this is provided by the RDAO option rdao. </del> <ins> The IPv6 Neighbor Discovery option RDAO rdao can do that. </ins> <del> If the address configuration of the network is performed via DHCP, this could be provided via a DHCP option (no such option is defined at the time of writing). </del> <ins> When DHCP is in use, this could be provided via a DHCP option (no such option is defined at the time of writing). </ins> Finally, if neither the device nor the network offers any specific configuration, the device may want to employ heuristics to find a

Please expand and add reference for 6LBR. Using 'modern' technologies (cfr LP-WAN WG) could also add justification to section 3.5. -- Section 4.1 -- About "coap://[MCD1]/.well-known/core?rt=core.rd*", what is the value of MCD1 ? The IANA section discuss about it but it may help the reader to give a hint before (or simply use TBDx that is common in I-D). Any reason to use "address" rather than "group" in "When answering a multicast request directed at a link-local address" ? Later "to use one of their own routable addresses for registration." but there can be multiple configured prefixes... Which one should the RD select ? Should this be specified ? As a co-author of RFC 8801, I would have appreciated to read PvD option mentionned to discover the RD. Any reason why PvD Option cannot be used ? -- Section 4.1.1 -- I suggest to swap the reserved and lifetime fields in order to be able to use a lifetime in units of seconds (to be consistent with other NDP options). -- Section 5 -- May be I missed it, but, can an end-point register multiple base URI ? E.g., multiple IPv6 addresses. -- Section 9.2 -- For information, value 38 is already assigned to RFC 8781. -- Section 2 -- The extra new lines when defining "Sector" are slighly confusing. Same applies to "Target" and "Context". This is cosmetic only.


Question: 10. <del> The first example shows a deprecation header field without date information: The second example shows a deprecation header with date information </del> <ins> The first example shows a deprecation header with date information </ins> and a link to the successor version: <del> The third example shows a deprecation header field with links for the successor version and for the API's deprecation policy.  In addition, it shows the sunset date for the deprecated resource: </del> <ins> The second example shows a deprecation header field with links for the successor version and for the API's deprecation policy.  In addition, it shows the sunset date for the deprecated resource: </ins>

Looks good to me.
... are considered a 'bad smell'. Instead of a date vs. a fixed string, could we just say that a date in the past is equal to 'true'?
i guess we could. and we already say that a date in the past means that the resource is deprecated. the motivation to allow a flag was to not force services to make up a date when they don't have one and simply want to flag something as deprecated. but we could also "force" them to make up a date by not allowing the "true" flag. i am fine either way and i do see the point that the syntax may cause some implementations to not parse the field correctly. maybe others can weigh in as well?
FWIW, I see it like Expires -- if it's already stale, you just assign a date in the past.
i could definitely live with such a design.
One use case was to align the header's usage with API contract as defined using OpenAPI. Having boolean helps align this header with OpenAPI's flag which does not require date. Forcing API developers to add a random date in the past in case if it is not available due toe various reasons would not be desirable for various other reasons (SLA?). Although, I wish that OpenAPI adds date for . >If the deprecation date is not known, the header field can carry the simple string "true", indicating that the resource context is deprecated, without indicating when that happened: On Jul 31, 2021, at 06:46, Mark Nottingham NAME wrote: FWIW, I see it like Expires -- if it's already stale, you just assign a date in the past.
For Expires, January 1 1970 (epoch 0) is widely used.
NAME I wish OpenAPI supported deprecated date also. But when we do, it won't be with a property that can be boolean or date.
Ok NAME thanks for clarification on the OpenAPI side of things. I agree. We can just use date. There are some implementations out there, I would not know if any of those use boolean but since we are not an RFC yet, such a change should not be unexpected.
it seems like we can safely remove the alternative syntax. i have created a PR asking for review by NAME
LGTM


Question: servers set up their HPKE context and decrypt ClientECH as follows: ClientHelloOuterAAD is computed from the second ClientHelloOuter as <del> described in authenticating-outer. </del> <ins> described in authenticating-outer.  The "info" parameter to SetupPSKR is computed as above. </ins> If the client offered ECH in the first ClientHello, then it MUST offer ECH in the second.  Likewise, if the client did not offer ECH

The spec describes an optional trial decryption mode, but most of the text contradicts it. This PR fixes the text up and tries to unify their processing models. In doing so, it flips the error handling from decrypterror to fallback to be consistent. This, combined with the ClientHelloOuterAAD change, plugs an active sticking out attack for free. It also makes easier because GREASE configid collisions with real configids are now harmless. Along the way, NAME and NAME observed that we're not authenticating the ECHConfig at all. (It used to be authenticated by way of the configid, which was a digest.) Instead, just pass the ECHConfig into the info field of the HPKE context. They also noticed the server rule about PSKs on ClientHelloOuter didn't work with GREASE. Instead, we can simply remove it.
This matches the acceptance signal length, and we've already accepted that probability of collision.


Question: prevents passive observers from correlating sessions unless tickets are reused.  Note: because ticket lifetimes are restricted to a week, 32 bits is enough to represent any plausible age, even <del> in milliseconds.  External tickets SHOULD use an obfuscated_ticket_age of 0; servers MUST ignore this value for external tickets. </del> <ins> in milliseconds.  For identities established externally an obfuscated_ticket_age of 0 SHOULD be used, and servers MUST ignore the value. </ins> A list of the identities that the client is willing to negotiate with the server.  If sent alongside the "early_data" extension

Ticket is a term that refers to a PSK identity established using an handshake. For out-of-band PSK, we do not use the term.


Question: on.  Connections in a Connection Group share all Protocol Properties that are not applicable to a Message. <ins> In addition, incoming entangled Connections can be received by creating a Listener on an existing connection: </ins> Changing one of these Protocol Properties on one Connection in the group changes it for all others.  Per-Message Protocol Properties, however, are not entangled.  For example, changing "Timeout for

This adds an explicit Listener object to the API ( to clarify behaviour of multi-streaming protocols ( clarify behaviour and enable re-use of Preconnections (
We talk about listen objects in architecture and implementation, but not in the API. Changes needed: Let return a Listener Move the the Listener Allow Preconnection to be used multiple times.
This issue popped up while discussing and seem to be a wired QUIC multi-streaming issue, possible affecting SCTP too): When a multi-streaming protocol like QUIC allows both ends to open new streams (e.g. by cloning the QUIC connection representing the stream), the both side needs a way to get a ConnectionReceived event for a new stream. That might result in the following weird pattern: I think this needs to be documented somehow and we may need to add a Selection Property do turn off this behaviour.
Calling is an active open. Once the connection is open, the peer can open new streams, but those would surely be events on the not on the .
NAME I am not sure with this one: assuming you have a bunch of ? The first one? What happens if I close the first one?
That's a good point, and I'm not sure I know the answer, but I don't think the should fire the events. A is a potential connection, yet to be instantiated, but these connections come from an already active connection. I've never been entirely comfortable with cloning a connection as the multi-streaming abstraction. This is perhaps the first scenario where it struggles though.
I do not understand the pattern in the example. You do not get a ConnectionReceived after an active open, you need a Listen?
NAME Your assumption is true for TCP, but not for multi-streaming transports like QUIC. With QUIC, you can indeed get additional TAPS connections (QUIC streams) based on an existing, initiated connections. The question is how to handle this. NAME A possible way out would be making itself is returned by an event then.
NAME the TAPS interface is the same weather you have TCP or QUIC underneath. For TAPS an active open generates a READY event not a ConnectionReceived? I do not think your example is a valid TAPS sequence.
NAME the Ready event is not shown in the example (it would be within the first ). The problem I raised is how to model the addition of streams to a multi-streaming connection.


Question: on.  Connections in a Connection Group share all Protocol Properties that are not applicable to a Message. <ins> In addition, incoming entangled Connections can be received by creating a Listener on an existing connection: </ins> Changing one of these Protocol Properties on one Connection in the group changes it for all others.  Per-Message Protocol Properties, however, are not entangled.  For example, changing "Timeout for

In case of QUIC, additional streams can be initiated by the server/listening side of the QUIC connection. If we model QUIC streams as TAPS connections, this results in events at the client (and server) side for each new QUIC stream.
NAME agree we could add , although it's a significant shift in the model. If we did that, we might also want to revisit as the way of creating a new stream on a connection, in favour of a method on . NAME did you implement this with QUIC? How does your implementation work?
I also see a problem with the communication pattern here. To me, modelling a stream as a TAPS connection means that for every new connection that a peer creates (be it a stream of an existing connection or not), I'll have to listen. So: if I expect 5 incoming connections, which may e.g. be 1 connection with 1 stream and 4 later-added streams below the API, I'll have to listen 5 times. What this also means is that the grouping notion should be a readable property - I believe that we currently only describe it as something that's actively created via clone(). Regarding code, no idea how NAME has done this, but I believe that the NEAT implementation is like I describe here. For more details on this specific aspect, see: URL
NAME We create a Listener from a Connection to handle inbound streams associated with the same parent transport connection. NAME Currently, our Listener object doesn't require calling Listen() for each new connection—you can get the event invoked many times, so it doesn't require knowing how many streams may be opened by the peer. In order to get back pressure, we're talking about having a window for how many new inbound connections will be allowed at a time.
Ok, that also sounds perfectly reasonable. Actually it seems that this (receiving multiple ConnectionReceived events on one Preconnection) is already supported by our current text, sorry for missing this! So... what is the problem we're discussing here - what do we need to change in the text? I think we need only the following: do we have a use case for one Listener getting multiple Connections without having these Connections grouped? (I guess not? Grouping is not a promise of multi-streaming.)


Question: on.  Connections in a Connection Group share all Protocol Properties that are not applicable to a Message. <ins> In addition, incoming entangled Connections can be received by creating a Listener on an existing connection: </ins> Changing one of these Protocol Properties on one Connection in the group changes it for all others.  Per-Message Protocol Properties, however, are not entangled.  For example, changing "Timeout for

If so, we need the ability to query whether connections are grouped (currently grouping is only created actively via "clone"). Otherwise, we can just statically say that all Connections that are created from the same Preconnections are grouped. some kind of ConnectionReceived event for the Rendezvous case, with text saying that all Connections created off the same PreConnection are grouped. (right?) a way to provide back pressure. Here, we already have PreConnection.Stop(). In the interest of keeping things simple, do we think that intelligently switching between a listening and a non-listening mode would be enough? If so, maybe we should have a call similar to Stop which stops listening, but does not dispose of the PreConnection, such that Listen could be called again. Maybe have an "End" call which stops and disposes, and let Stop only stop listening (because "Stop", to me, indicates only stopping but nothing else).
NAME This solution sounds very reasonable – I guess we should do it the same way for TAPS and add that as Text to the API NAME Some comments: It depends – if writing a server, you might want all streams of a multi-streaming connection grouped, but not all multi-streaming connections received through the same listener. So the behaviour wether to group should be a property of the Listener. I would not group connections received through the same Rendezvous (analogous to server-style listener). We might want to add a property to the listener
NAME I agree, but: just because groups may encompass more than the Connections from one Listener doesn't mean that it would be bad to always group the Connections from one Listener (i.e., group them among themselves, but maybe group them with others too). Besides, I think that wouldn't be the listener deciding anyway. Just to understand this, are you saying "no, see my argument for case 1" ? Then we're just discussing case 1, my answer is above. Otherwise I'd say: why not? yes ... but what do you mean with ? We have , just the semantics are not what I suggested. Regarding , I think that's a good idea - my own proposal was me overdoing "keep it simple, let's not add features". Nobody needs to use this unless they want to.
NAME I guess the answer really depends on what a connection group is for you.


Question: on.  Connections in a Connection Group share all Protocol Properties that are not applicable to a Message. <ins> In addition, incoming entangled Connections can be received by creating a Listener on an existing connection: </ins> Changing one of these Protocol Properties on one Connection in the group changes it for all others.  Per-Message Protocol Properties, however, are not entangled.  For example, changing "Timeout for

I always saw connection groups as an abstraction for multi-streaming connections (or their emulation) – therefore I see no use for grouping connections from multiple listeners. My opinion is auto-grouping for multi-streaming is fine, otherwise it is not. really falls out of 1 I want your semantics, but call it
NAME Me too. I can imagine other things ( this paper of ours comes to mind: URL ), but generally I agree and don't think we should complicate the API for this. But I'm getting confused: you wrote "you might want all streams of a multi-streaming connection grouped, but not all multi-streaming connections received through the same listener". That sounded to me like you want to support multiple streams, but from several listeners?! ACK Agreed!
NAME let me elaborate on this… You might want all streams of a multi-streaming connection grouped, e.g., all streams within a QUIC connection You might not want all multi-streaming connections (e.g., QUIC connections) received through the same Listener object grouped You definitely do not want all all streams of all QUIC connection received through one listener grouped (except if you have hierarchical groups that allows you to sort that out the cases above)
I agree with all this. Anyway I think it's a moot point: whether they're grouped or not is not up to the listener to decide? So grouping needs to be something that can be queried.
Ok – fair enough – but I still think the Listener is the right place to configure whether connections that come out of it should be grouped by default or not.
Not unless we have a concrete idea on what to do with this information inside the transport system. => I think no text update is needed as a result of this issue and lean towards closing it...
I don't think we really need a text update for the grouping, but for the original question. To address the handling of incoming streams in multi-streaming connections, I would like to have the solution NAME outlined reflected in the API.
One question on this, for NAME the description of your Listener object being able to accept multiple events, is that how it works in general or was that specif for a multi-streaming scenario? As specified I am not sure that our Listen action does not allow multiple ConnectionReceived events? The text says
NAME The listener object for all cases (both multi streaming and receiving brand-new transport connections) allows multiple events.


Question: on.  Connections in a Connection Group share all Protocol Properties that are not applicable to a Message. <ins> In addition, incoming entangled Connections can be received by creating a Listener on an existing connection: </ins> Changing one of these Protocol Properties on one Connection in the group changes it for all others.  Per-Message Protocol Properties, however, are not entangled.  For example, changing "Timeout for

I think the existing text is a bit ambiguous, but it seems that "listening continues" implies that the event can certainly fire again.
Revisit after is done
Regarding this text: This seems to imply that the Preconnection object, which may be full of many carefully tuned settings that could be useful for another Connection, is no longer usable. While I understand that the specific Preconnection cannot change for a Connection, this is inconvenient to the application. I see two good options to solve this: Make a deep copy of the Preconnection upon Initiate(), and say that a Preconnection may be used or changed but changes can no longer influence the Connection (this is what Network.framework currently does) Allow a URL() method to let the applications do the deep copy themselves when and if they want to re-use.
+1 to reusing the preconnection. Do you even need a deep copy. The connection is a new object that should be independent of the preconnection anyway, no? Another thought: Are there actually ways to get different connections out of the preconenction. E.g. you do racing and end up with two open connections and (suddenly) want to use both...?
I'd like to see this as well. To me it makes most sense to allow calling Initiate() on the same Preconnection multiple times to get multiple Connections, but not allow to change this Preconnection anymore after the first Initiate. This way it would be similar to Listen() and Rendezvous(), where we have a Preconnection that yields multiple Connections, and that cannot be changed anymore after Listen() or Rendezvous(). So here we already have a binding between the Preconnection and the Connections that come out of it. If the application wants to change the Preconnection before re-using it, I'd be in favor of letting it explicitly clone the Preconnection - not sure if we actually want to call it clone() though, because we already have Connection.Clone(), which creates a Connection Group, a completely different thing.
Why do you think it should not be allowed that a preconnection can be changed after the first initiate? If you don't change it you should get the same kind of connection, if you change it you might get something different. Your choice!
I wanted the API contract to be similar for different forms of Connection establishment. But I may be overthinking this.


Question: on.  Connections in a Connection Group share all Protocol Properties that are not applicable to a Message. <ins> In addition, incoming entangled Connections can be received by creating a Listener on an existing connection: </ins> Changing one of these Protocol Properties on one Connection in the group changes it for all others.  Per-Message Protocol Properties, however, are not entangled.  For example, changing "Timeout for

First, I like the idea of reusing Preconnections. I am not sure whether we should define now whether they should be changeable after the first initiation. There might be kinds of Preconnections where this is a good idea, there might be others where it is not. I anticipate one can realize connection pools as a sub-class of Preconnection. In this case, in such cases, it should not be possible to change a Preconnection.
So the difference is if you think you morph a preconnection into a connection, or if the preconnection create the connection. i think the first think does not make sense because their are two completely different things; they have not actions or events in common.
NAME The morphing one has its beauty for modeling TCP fastopen / 0-RTT data.
Whether it makes sense to re-use a perhaps depends on how fully specified it is? Reusing a completely specified , that will just re-open an identical 5-tuple as an existing might not make sense. Reusing a partially specified , e.g., with the source port left as a wildcard to new connections can open without conflicts, seems reasonable.
NAME right, using the exact same set of fully-specified properties isn't going to work. But having a partially specified one and copying it, or modifying one that was used (by switching out the Remote, etc) would be useful.
This might work better the other way -- on , the Preconnection corresponding to the initiated/initiating connection gets deep-copied into the new connection, leaving the existing Preconnection in the state that it was. That deep copy, inside the connection, cannot be reused, but the existing one could be. (This probably only works for connections on which you . turns the preconnection into a listener from which multiple , each of which will have their own deep copy of the listener, will spawn. might be even weirder, but there's a potentially bigger win to allowing reuse, but I don't quite have my head around how it would work)
So i think there is actually not that much too deep copy because a preconception is not a super class of a connection. At the moment when you call initiate or rendezvous the preconception should create a connection and store all information regarding this connection in the connection object which is later returned.


Question: on.  Connections in a Connection Group share all Protocol Properties that are not applicable to a Message. <ins> In addition, incoming entangled Connections can be received by creating a Listener on an existing connection: </ins> Changing one of these Protocol Properties on one Connection in the group changes it for all others.  Per-Message Protocol Properties, however, are not entangled.  For example, changing "Timeout for

The only thing that needs "copying" is the properties but you need to create a new object anyway because preconnection properties have preferences and connection properties not but have to be marked as mutable or unmutable. These two things are also not the same. So the only that that's left to copy maybe are the endpoints. Not sure if the preconnection and connection both have a copy of the endpoints or if an endpoint only exists once and both have a reference (which means if the endpoint gets somehow updated that's relevant for both) or maybe even the connection does not need a reference to the endpoint anymore...?
NAME right – but I don't know a way of specifying "a is consumed if fully specified, else may be reusedin any current programming language. Maybe tracking lifetimes so closely doesn't matter though, and we can just write this in the draft.
I have no problem with an Interface where some Preconnections can be reused and others can not. That makes a pretty nice case for -- preconnection reuses itself for multiple incoming connections. For ` I see this API-wise as some kind of listen called at both sides.
Side meeting says we can reuse the initiate call. Implementation should specify that a deep copy is made on Initiate() or Listen()
Will be trivial to fix after is done
Sorry to reopen an old issue, but when reading the current API draft, I noticed that it still says that reusing the Preconnection is possible for Listeners, but not possible for Initiate() and Rendezvous(). For example, see Section 6.1: "The Initiate() Action consumes the Preconnection […]" From what I read in this issue, I think Preconnections should be allowed to be reused for Initiate() and Rendezvous() as well (possibly with a note on deep-copy).
This looks just right to me, thanks a lot for doing this! In particular having read again, I believe that NAME should definitely have the last word on this one. So I'll go with whatever NAME says.


Question: depending on their current availability and capabilities as well as application requirements, thus avoiding silo like solutions.  One of the crucial enablers of such design is the ability to discover <del> resources (machines -- endpoints) capable of providing required information at a given time or acting on instructions from the end users. </del> <ins> resources (and thus the endpoints they are hosted on) capable of providing required information at a given time or acting on instructions from the end users. </ins> Imagine a scenario where endpoints installed on vehicles enable tracking of the position of these vehicles for fleet management

as suggested by Russ in the genart review: NAME did I get the intention of the expression right?
LGTM


Question: over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery. <ins> This document updates RFCs 4492, 5705, and 6066 and it obsoletes RFCs 5077, 5246, and 6961. </ins> 1. RFC EDITOR: PLEASE REMOVE THE FOLLOWING PARAGRAPH The source for this

The I-D checklist requires that updates and obsoletes be included in the abstract; thought RFC. I personally feel this is [redacted] stupid, but I do not think that we should risk a process appeal to fight this battle.


Question: transport mode, it would only be possible to send packets originated by the ACP node itself. <del> IKEv2 authentication MUST use authentication method=1 ("RSA Digital Signature") for ACP certificates with RSA key and methods 9,10,11 for ACP certificates with ECC key according to the keys size/curve. A certificate payload with the ACP certificate MUST be included during IKEv2 authentication to support the ACP domain membership as described in certcheck, because it is using additional elements of the ACP certificates.  ACP peers are expected to have the same set of Trust Anchors (TA), so a certificate path MUST only be included in the signaled payload when the path contains intermediate certificates not in the TA set, such as sub-CAs (see acp-registrars). IPsec MUST support ESP with ENCR_AES_GCM_16 (RFC4106) due to its higher performance over ENCR_AES_CBC.  ACP MUST NOT use any NULL encryption option due to the confidentiality of ACP payload that may not be encrypted by itself (when carrying legacy management protocol traffics as well as hop-by-hop GRASP).  These requirements are based on RFC8221 but limited to the minimum necessary options because there is no need for interoperability with legacy equipment for ACP channels, instead any such backward compatibility would reduce the minimum security or performance required for ACP channels or increase the implementation complexity of the ACP. </del> <ins> ACP IPsec implementations MUST support ESP with ENCR_AES_GCM_16 (RFC4106) due to its higher performance over ENCR_AES_CBC.  ACP MUST NOT use any NULL encryption option due to the confidentiality of ACP payload that may not be encrypted by itself (when carrying legacy management protocol traffics as well as hop-by-hop GRASP).  When using AES encryption, 256-bit keys MUST be used.  AES-GCM is an AEAD cipher mode, so no ESP authentication algorithm requirement is needed. </ins> Once there are updates to RFC8221, these should accordingly be reflected in updates to these ACP requirements, for example if

During IETF 106 I solicited some feedback on the ACP IPsec/IKEv2 usage from Valery Smyslov; I've tried to digest that feedback into new text here. Some aspects are still subject to change. I also made a minor tweak to the DTLS section to bring it into parity with the IPsec one.
Merging first, then fixing.


Question: A packet that does not increase the largest received packet number for its packet number space (packet-numbers) by exactly one.  A <del> packet can arrive out of order if it is delayed or if earlier packets are lost or delayed. </del> <ins> packet can arrive out of order if it is delayed, if earlier packets are lost or delayed, or if the sender intentionally skips a packet number. </ins> An entity that can participate in a QUIC connection by generating, receiving, and processing QUIC packets.  There are only two types

A sender can intentionally skip a packet number, causing the receiver to treat a packet as "Out-of-order". From NAME comment on


Question: discovered.  Such elements may include classes of data, major roles, and role interactions.  This scenario also informs protocol and data model development in support of vulnerability assessment, as part of <del> overall posture assessment.  Vulnerability discovery, disclosure, and publication is out of scope. </del> <ins> overall posture assessment (see implementation-examples for examples of solutions that support this scenario). Vulnerability discovery, disclosure, publication, and prioritization is out of scope.  However, given the importance of prioritization in an enterprise's vulnerability assessment process, it is discussed in priority. Information on how the scenario aligns with SACM and other existing work is discussed in sacm-usage-scenarios through alignment-with- other-existing-works. </ins> 2.

We should review the appendices and include the appropriate references to them through the main body of the document.


Question: 21.13. Deployments should limit the ability of an attacker to target a new <del> connection to a particular server instance.  This means that client- controlled fields, such as the initial Destination Connection ID used on Initial and 0-RTT packets SHOULD NOT be used by themselves to make routing decisions.  Ideally, routing decisions are made independently of client-selected values; a Source Connection ID can be selected to route later packets to the same server. </del> <ins> connection to a particular server instance.  Ideally, routing decisions are made independently of client-selected values, including addresses.  Once an instance is selected, a connection ID can be selected so that later packets are routed to the same instance. </ins> 21.14.

This was just old and needed a little bit of a refresh. Removing the recommendation, which was counter to established views and unnecessary. I will let others determine whether this is editorial/design.
NAME said:
I think that the point of this section is to highlight the possibility that routing based on client-selected values exposes servers to load that is balanced under client - and therefore attacker - control. I don't think that it needs to include such a strong recommendation. If people deploying load balancers are not concerned about this, then that is good. That makes the recommendation less good. As this is very old text, it needs a bit of a cleanup anyway. I'm going to suggest something along the lines of my statement above in a pull request and we can polish the wording there. I don't think that we should remove the Retry SCID language. That remains an option for servers, even if they don't want to exercise the option (whether load balancers look at Retry tokens is very much down to how the various functions are distributed). What could happen is that the Retry SCID is chosen so that the next initial can be routed as though it were chosen by a client, but in such a way as it results in the connection being sent to a lightly-loaded server instance. That is, if the load balancer routes inchoate Initials based on connection ID, knowledge of that routing algorithm is used to direct traffic. That said, I understand that what is more likely here is that Initials with inauthentic Destination Connection ID fields will be routed using other information: round-robin, random, five-tuple, or whatever.
I think you're proposing that the text I quoted be deleted. That is satisfactory, and what I would recommend as well.
Returning to an open state as the chairs directed in their plan.
Closing this now that the IESG have approved the document(s).
To be safe, let's mark this design.


Question: 3. <del> The Transport Services API is the basic common abstract application programming interface to the Transport Services Architecture defined in the TAPS Architecture I-D.ietf-taps-arch. </del> An application primarily interacts with this API through two Objects: Preconnections and Connections.  A Preconnection object (pre- establishment) represents a set of properties and constraints on the

, , , , , .
In 8.1.1 the second sentence is convoluted. Is there a way to restate it without as many nots, nons, an different zeros?
Do you really mean "host" at "(endpoints) SHOULD represent the same host" in section 6, or do you mean something more like service, given that an endpoint may configured with a DNS name?
actually we mean service, good catch.
The "reformatted where necessary" part of the requirement in the last paragraph of 4.1 makes the MUST NOT almost impossible to conform to. I think I understand what the paragraph is trying to say, but the current formulation leaves the reader guessing. I think you are trying to say "Avoid using any of the terms listed as keywords in the protocol numbers registry as any part of a vendor or implementation-specific property name".
The first sentence-paragraph of section 4 is complex. Please break it apart.
has a comment that's too long for the text version
In the text version of the document, the last paragraph before 3.1.3 has some markup (~~~) that has leaked through.
As you can tell, I don't think the documents do what the first sentence of the API summary claims. This document would not lose anything if you deleted the sentence.
Agreed, we can lose this sentence.
Why? Removing this makes no sense to me.
For one, it's redundant - it only repeats what we already say earlier twice.
Ah, I see - so just this one instance..... then go ahead, we don't need to say something twice.


Question: The requested operation cannot be served over HTTP/3.  The peer should retry over HTTP/1.1. <del> Error codes of the format "0x1f * N + 0x21" for integer values of N are reserved to exercise the requirement that unknown error codes be treated as equivalent to H3_NO_ERROR (extensions).  Implementations SHOULD select an error code from this space with some probability when they would have sent H3_NO_ERROR. </del> <ins> Error codes of the format "0x1f * N + 0x21" for non-negative integer values of N are reserved to exercise the requirement that unknown error codes be treated as equivalent to H3_NO_ERROR (extensions). Implementations SHOULD select an error code from this space with some probability when they would have sent H3_NO_ERROR. </ins> 9.

Clarify reserved values for stream types, settings identifiers, frame types, and error codes. 0x1f N + 0x21 for the value of N = -1 is 0x02. Literal interpretation of the current text includes this as a reserved value. The parenthetical examples given in Section 11.2 make it clear that this was not the intention, rendering this PR editorial. The main motivation of this PR is not that the current text is inconsistent, but that parenthetical examples from 11.2 are necessary to correctly interpret the definitions in sections 6.2.3, 7.2.4.1, 7.2.8, and 8.1. Alternative wordings could be: "0x1f N + 0x21 for N = 0, 1, 2, ..." "0x1f N + 0x02 for positive integer values of N" "0x1f N + 0x02 for N = 1, 2, 3, ..." "0x21, 0x21 + 0x1f, 0x21 + 2 * 0x1f, ..." "a value of at least 0x21 with a remainder of 0x02 modulo 0x1f" "a value of at least 0x21 that is congruent to 0x21 modulo 0x1f" none of which is better than what this PR proposes.


Question: In some cases, a CA running an ACME server might have a completely external, non-ACME process for authorizing a client to issue for an <del> identifier.  In these case, the CA should provision its ACME server </del> <ins> identifier.  In these cases, the CA should provision its ACME server </ins> with authorization objects corresponding to these authorizations and reflect them as already valid in any orders submitted by the client.

Addresses Martin Stiemerling's TSV-ART review
Merging based on NAME review
On the mailing list, Rifaat Shekh-Yusuf pointed out these issues: Section 7.3.5, first paragraph, second line: A "bind" word is missing between the words "to" and "an" Section 7.4.1, second paragraph, second sentence: "case" should be "cases". When the server builds the authorization object, the document is stating that the response would include "challenges" and "combinations". Remove the "combinations" as it is not being used. Section 7.5.1, the Request URIs in the examples: Should not this be /acme/authz/1234/0?
In "Responding to challenges," we use the term "response fields." These fields are defined by each challenge type, but are not described as "response fields" there. We should add a heading describing them as such in the challenge type definitions.
The other challenges don't expect you to post a payload containing a type field, so it's inconsistent for OOB-01 to do so. It should just take an empty object "{}" as its payload.
This seems fine. It seems to be protected from replay by the and parameters. I think we're OK leaving the challenge name at "oob-01", since this isn't a breaking change.


Question: 6. One of the content types supported by the TLS record layer is the <del> alert type.  Alert messages convey the severity of the message (warning or fatal) and a description of the alert.  Alert messages with a level of fatal result in the immediate termination of the connection.  Like other messages, alert messages are encrypted as </del> <ins> alert type.  Like other messages, alert messages are encrypted as </ins> specified by the current connection state. <ins> Alert messages convey the severity of the message (warning or fatal) and a description of the alert.  Warning-level messages are used to indicate orderly closure of the connection (see closure-alerts). Upon receiving a warning-level alert, the TLS implementation SHOULD indicate end-of-data to the application and, if appropriate for the alert type, send a closure alert in response. Fatal-level messages are used to indicate abortive closure of the connection (See error-alerts).  Upon receiving a fatal-level alert, the TLS implementation SHOULD indicate an error to the application and MUST NOT allow any further data to be sent or received on the connection.  Servers and clients MUST forget keys and secrets associated with a failed connection.  Stateful implementations of session tickets (as in many clients) SHOULD discard tickets associated with failed connections. All the alerts listed in error-alerts MUST be sent as fatal and MUST be treated as fatal regardless of the AlertLevel in the message. Unknown alert types MUST be treated as fatal. </ins> %%% Alert Messages 6.1.

NAME NAME PTAL
LGTM
lgtm
Don't forget no_certificate.
Not relevant: nocertificateRESERVED(41), / fatal / , Martin Thomson EMAIL wrote:
Right. I just noticed that we send an empty certificate instead.


Question: appropriate).  Note that when considering a MediaStreamTrack that is producing rotated video, the unrotated resolution MUST be used.  This is required regardless of whether the receiver supports performing <del> receive-side rotation (e.g., through CVO), as it significantly simplifies the matching logic. </del> <ins> receive-side rotation (e.g., through CVO TS26.114), as it significantly simplifies the matching logic. </ins> For the purposes of resolution negotiation, only size limits are considered.  Any other values, e.g. picture or sample aspect ratio,

Note that the use of CVO in webrtc is described in URL
NAME feel free to rewrite however and merge. I just wanted to get the xref in.
We mention it in the imageattr section. This is required regardless of whether the receiver supports performing receive-side rotation (e.g., through CVO), as it significantly simplifies the matching logic.
NAME , can you look into this? Not WGLC2 blocking.
will do - I seem to recall it is a 3GPP ref but will try and track down.


Question: absolute index less than the Base, this representation starts with the '01' two-bit pattern. <del> Only the header field name stored in the static or dynamic table is used.  Any header field value MUST be ignored. </del> The following bit, 'N', indicates whether an intermediary is permitted to add this header to the dynamic header table on subsequent hops.  When the 'N' bit is set, the encoded header MUST

Use more uniform and more specific language in description of instructions, like "follows" instead of "includes" or implicit mention of a field. Add references to integer and string encodings where missing. Prefer internal references to external ones (also in Section 1.2). Explicitly allow a header block to not have any instructions after the mandatory prefix. Refer to Literal Header Field With Name Reference section in Literal Header Field Without Name Reference instead of verbatim repeating text on 'N' bit. Reshuffle sentences, insert references instead, remove sentences where references suffice.
Mostly good improvements; a few things to fix up further.


Question: field ensures that responses have unique AEAD keys and nonces even when requests are replayed. <del> 7.4.1. </del> <ins> 7.5.1. </ins> Clients SHOULD include a "Date" header field in Encapsulated Requests, unless the Oblivious Gateway Resource does not use "Date"

NAME noted that it was important to note that the Gateway needs to be trusted if gateway != target. As a practical matter, that means that you probably want gateway == target.
Hi, Since the gateways are seeing request/response pairs, there is a potential here for a side-channel attack at the gateway itself or at a relay. (if I understood the draft correctly - if not, please clarify my misunderstanding here). Are there mitigations planned for this type of issue that you could expand on in the Security Considerations section perhaps?
Does the new text in address this concern?
I don't think so, because the claim is the gateway does not have intimate knowledge of the contents of the request/response. If that assertion is true, the gateway shouldn't be able to ascertain information about the actual contents from those pairs (directly or indirectly, via a side-channel attack). If the burden is on the application developer to ensure that request/response pairs traversing the gateway are to be resilient to side-channel attacks of those pairings, then it would be good to explicitly call that out in this spec (perhaps in the security considerations section?) Thoughts?
NAME the gateway necessarily sees all request and response pairs, and will therefore always learn information about each transaction. This is fundamental to the design. Whether or not the gateway uses that information for malicious purposes, e.g., by providing different responses to different requests for the same target resource, depends on the trust model. And the change in addresses that. I don't think further text is needed here.
"Finally, a relay can also generate responses, though it assumed to not be able to examine the content of a request (other than to observe the choice of key identifier, KDF, and AEAD), so it is also assumed that it cannot generate an Encapsulated Response." I feel that a relay could certainly perform a side-channel attack here as well using R/R pairings.
Can you please be more specific here? What type of attack could the relay do to violate client privacy that is not already documented in the draft?
Typically in HTTPs scenarios, it is more difficult to perform side channel attacks as a flow observer, especially if multiplexing of requests and responses are performed.


Question: field ensures that responses have unique AEAD keys and nonces even when requests are replayed. <del> 7.4.1. </del> <ins> 7.5.1. </ins> Clients SHOULD include a "Date" header field in Encapsulated Requests, unless the Oblivious Gateway Resource does not use "Date"

In this design, if I understand it correctly, the requests and responses are being broken out into distinct exchanges that the relay can see and therefore it makes it easier for a relay to perform these types of attacks that would be more difficult had the relay not been used in the first place. If my understanding of the protocol is incorrect here, please feel free to point that out.
You seem to be describing fingerprinting attacks, wherein the observer uses features extracted from otherwise encrypted traffic to try and learn information about the underlying (unencrypted) data. Yes, the relay does have a more fine-grained view of each exchange compared to a network observer in this protocol since it can see explicit message boundaries, and that might impact the efficacy of these attacks. This is partly already addressed in the document: We could extend this to note the relay's view of message boundaries. I don't think any additional text is needed for the gateway.
Whatever you feel is best. I think some language around the message level risks this creates vs non-relay scenarios might be helpful. Does the client intentionally break things up in a way that crosses the underlying application message boundaries (e.g. more like packetization) with a relay? I have more questions about the gateway functionality that we can discuss separately.
This means that the client really needs to trust that the gateway doesn't muck with it. As a practical matter, this incentivizes clients to choose a gateway that is effectively the same entity as the target. They don't have to, but the amount of trust required of the gateway is higher if gateway and target aren't operated by the same entity. We touch on this, but we could be clearer about it.


Question: 4.4. <del> Flow control provides a means of managing access to the limited </del> <ins> QUIC flow control provides a means of managing access to the limited </ins> buffers endpoints have for incoming data.  This mechanism limits the amount of data that can be in buffers in endpoints or in transit on the network.  However, there are several ways in which limits can

This mainly wiggles the existing text around and tries to fully qualify transport vs application to help explain the ways an implementation might do things, which is independent of how an application protocol might be designed (for example H3 doesn't require incremental processing but most people come to a realizatopm that it is the best way to do things).
The new text is good and clear, but it doesn't really explain that the when credit is released at the receiver, could we say a little more: it takes 1/2 RTT for cerdit to reach the sender, that causes new data to be released, for a large RTT, this means that credit has to be sufficient to avoid blocking or to be sent promptly, otherwise transfers will stall for periods of an RTT. (I know TCP does this stuff for the app and grows the window, but QUIC I suspect needs something to happen to release the credit). I know people closer to the Apps can write this sentence better than me; from my perspective I just see the effects when an app blocks or release credit in big chunks... over a large path RTT and the network performance suffers.
Thanks Gorry. I think I agree. How about I tweak "Timely updates can improve performance" paragraph to say "Timing of updates can affect performance". I can add a mention that the extension of credits on the data recever side is enacted by emitting MAXDATA/MAXSTREAM_DATA frames, which take at least a 1/2 RTT to reach the data sender side. I think the useful additional applicability statement to be made based on the above is that the data consumer read rate may be disjoint from the delivery rate and responsiveness of signalling channel back. For a highly asymmetric link, the download rate can be application-limited well below the theoretical bandwidth simply because an application is spending too much share of the time reading packets and not giving enough time to emit QUIC packets. Does that sound ok, or am I missing your ask?
This is definitely heading in the direction I was hoping, it helps avoid people developing on a LAN and then discovering the effects on other paths later. Please add something.
I've reworked the paragraph with my attempt to address NAME comment. I've introduced the terms uplink and downlink, which I'm not totally happy with. If someone has a better suggestion I'm all ears.
Issue: Sect 4.3.


Question: 4.4. <del> Flow control provides a means of managing access to the limited </del> <ins> QUIC flow control provides a means of managing access to the limited </ins> buffers endpoints have for incoming data.  This mechanism limits the amount of data that can be in buffers in endpoints or in transit on the network.  However, there are several ways in which limits can

Flow Control - we should have a subsection also encouraging timely credits This ID discusses flow control deadlock, whichI think is important. I suggest we should also note that timely release of flow control credit is also important (QUIC transport has some text to point to). This need is evident when the path has a large RTT, and there can be a large BDP, where the whole of operation of QUIC can be dominated by the way in which the application manages the flow credit. This might not be obvious, because the equivalent rwnd update in TCP is handled by the transport rather than the application.
The point is the audience for this draft is applications that use a quic library. I would assume that the actual credit handling is performed in the transport/in quic directly, usually without an interface for the application to directly impact it. Do you propose the application should have more direct impact on flow credit handling? I guess we can add a pointer to the right section in the transport draft but not sure we should/can say more here...?
I agree this seems mostly like a QUIC transport/library issue and I wouldn't expect the application to have much control here. I can imagine applications setting a max value?
I generally agree with Mirja and Ian. However, on a closer inspection of this section I think it would benefit from a crisper definition of what it means to read data vs. process data. Its a reasonable application mapping implementation design to read data out of the transport in order to release flow control but still buffer it (or just dropping it on the floor) in application space before processing that as application data.
NAME can you propose text?
I'm content that flow control is something the libraries need to get correct - the TCP people spent energy to get this automated, although QUIC's multi-streaming makes the trickier. Lucas text suggestion would improve things by making it clearer how the API is intended to be used.
NAME ?
I will add some text (just need to find the time).


Question: In order to facilitate asynchronous addition of clients to a group, it is possible to pre-publish initialization keys that provide some <del> public information about a user.  UserInitKey messages provide </del> <ins> public information about a user.  ClientInitKey messages provide </ins> information about a client that any existing member can use to add this client to the group asynchronously. <del> A UserInitKey object specifies what ciphersuites a client supports, </del> <ins> A ClientInitKey object specifies what ciphersuites a client supports, </ins> as well as providing public keys that the client can use for key derivation and signing.  The client's identity key is intended to be stable throughout the lifetime of the group; there is no mechanism to change it.  Init keys are intended to be used a very limited number <del> of times, potentially once. (see init-key-reuse).  UserInitKeys also contain an identifier chosen by the client, which the client MUST assure uniquely identifies a given UserInitKey object among the set of UserInitKeys created by this client. </del> <ins> of times, potentially once. (see init-key-reuse).  ClientInitKeys also contain an identifier chosen by the client, which the client MUST assure uniquely identifies a given ClientInitKey object among the set of ClientInitKeys created by this client. </ins> The init_keys array MUST have the same length as the cipher_suites array, and each entry in the init_keys array MUST be a public key for

Overall, this seems OK. Just using "InitKey" would be clear and less wordy.
I tried this and that led people to confuse and
Here's the Weekly Digest for : - - Last week 5 issues were created. Of these, 1 issues have been closed and 4 issues are still open. :greenheart: , by :greenheart: , by :greenheart: , by :greenheart: , by :heart: , by - - Last week, 9 pull requests were created, updated or merged. Last week, 3 pull requests were opened. :greenheart: , by :greenheart: , by :greenheart: , by Last week, 1 pull request was updated. :yellowheart: , by Last week, 5 pull requests were merged. :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by - - Last week there were 8 commits. :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by - - Last week there were 2 contributors. :bustinsilhouette: :bustinsilhouette: - - Last week there was 1 stargazer. :star: You are the star! :star2: - - Last week there were no releases. - - That's all for last week, please :eyes: Watch and :star: Star the repository to receive next weekly updates. :smiley: You can also .
These keys are Client one-time use keys, so "UserInitKey" seems like a strange name.
I'm fine with ClientInitKey, as long as a client is not only a physical endpoint. Changes in the architecture doc should make this clear soon.


Question: SSRF is somewhat more difficult to manage at runtime, and systems should generally refuse to fetch a URI if unsure. <ins> 12.33. Keys presented by value are allowed to be in only a single format, as discussed in key-format.  Presenting the same key in multiple formats is not allowed and is considered an error in the request.  If multiple keys formats were allowed, receivers of these key definitions need to be able to make sure that it's the same key represented in each field and not simply use one of the key formats without checking for equivalence.  If equivalence were not carefully checked, it is possible for an attacker to insert their own key into one of the formats without needing to have control over the other formats.  This could potentially lead to a situation where one key is used by part of the system (such as identifying the client instance) and a different key in a different format in the same message is used for other things, like calculating signature validity. To combat this, all keys presented by value have to be in exactly one supported format known by the receiver.  Normally, a client instance is going to be configured with its keys in a single format, and it will simply present that format as-is to the AS in its request.  A client instance capable of multiple formats can use discovery to determine which formats are supported, if desired.  An AS should be generous in supporting many different key formats to allow different types of client software and client instance deployments. </ins> 13. The privacy considerations in this section are modeled after the list

After discussion with NAME , this PR now makes keys single-format-only as previously suggested.
To edit notification comments on pull requests, go to your ._
Yaron: why are we sending a JWK as well as a cert? Are we checking that the cert contains the same public key as the cert? Justin: I would be OK with the different formats being mutually exclusive somehow. The AS would need to check that they’re the same and throw an error if not. But this would also let the RC send over whatever it’s got for its own keys every time.
The document has been changed to address this issue, copying my text that refers to the latest draft version: In Sec. 7.1 we allow the client to include multiple keys of different formats, provided they are "equivalent". This doesn't make sense, because the only reason to send multiple keys is that the sender suspects that the recipient doesn't understand one of the formats. But if that's the case, the recipient is not able to validate the MUST requirement that the two formats be equivalent. This could also lead to interesting key injection attacks. IMO we should only allow one key value/format for each request.


Question: minimizing the set of supported attestation procedures helps minimize the amount of information leaked through a token. <del> Each attestation procedure also has an impact on the overall system privacy.  Requiring a conjunction of attestation types could decrease the overall anonymity set size.  For example, the number of Clients that have solved a CAPTCHA in the past day, that have a valid account, and that are running on a trusted device is less than the number of Clients that have solved a CAPTCHA in the past day. Attesters SHOULD not admit attestation types that result in small anonymity sets. </del> <ins> The role of the Attester in the issuance protocol and its impact on privacy depends on the type of attestation procedure, issuance protocol, deployment model.  For instance, requiring a conjunction of attestation procedures could decrease the overall anonymity set size. As an example, the number of Clients that have solved a CAPTCHA in the past day, that have a valid account, and that are running on a trusted device is less than the number of Clients that have solved a CAPTCHA in the past day.  Attesters SHOULD NOT be based on attestation procedures that result in small anonymity sets. Depending on the issuance protocol, the Issuer might learn information about the Origin.  To ensure Issuer-Client unlinkability, the Issuer should be unable to link that information to a specific Client.  For such issuance protocols where the Attester has access to Client-specific information, such as is the case for attestation procedures that involve Client-specific information (such as application-layer account information) or for deployment models where the Attester learns Client-specific information (such as Client IP addresses), Clients trust the Attester to not share any Client- specific information with the Issuer.  In deployments where the Attester does not learn Client-specific information, the Client does not need to explicitly trust the Attester in this regard. </ins> Issuers trust Attesters to correctly and reliably perform attestation.  However, certain types of attestation can vary in value

In a successful issuance exchange, the attester provides the issuer with information about the client. The text in Section 3.2.1 points out that the way in which information about the client is combined could reduce anonymity set size in ways that affect privacy. Given that we have a chain of custody, I imagine that the privacy property here is about what the issuer learns about a client. More information means more information that might then propagate from the issue onward to the origin. This means that the attester needs to limit what it passes along to only that which is relevant. The client needs to trust the attester to do this. ... or does it? The text in Section 3.2.1 implies strongly that this anonymity set size is important, but the constraints on the client-issuer interaction, especially consistency rules, very much limits what the issuer can pass along to the origin. So maybe the system depends less on trusting the attester and more on the combination of the cryptographic properties of the token and the consistency system that mitigates against misuse. None of this appears in the privacy considerations. Should it?
On this point: "Clients do not explicitly trust Issuers." (Section 3.2.2) This would invalidate much of the discussion of anonymity sets in attestations. This is quite confusing. The client doesn't need to trust the issuer, because the issuer is unable to pass information on to others. However, the client cannot trust the issuer with information, so it has to trust the attester not to pass stuff along AND it has to use an anonymizing proxy to interact with the issuer so that nothing leaks. This is quite contradictory overall.
There are issuance protocols wherein the issuer learns information about the origin by design, like the . In this variant, if the attester were to pass information about the client on to the issuer, then the issuer would be able to reconstruct the (client, origin) pair, breaking the unlinkability goals. I agree that in the case where the issuer learns nothing about the origin in the protocol then reliance on the attester is lessened, but we need to make sure we accommodate future issuance protocols here. I'll think about ways in which we can try to make this more clear. This might go into the privacy considerations, as suggested.


Question: 7.6. For application-layer protocols where the Connection initiator also <del> sends the first message, the InitiateWithIdempotentSend() action combines Connection initiation with a first Message sent, provided that message is idempotent. </del> <ins> sends the first message, the InitiateWithSend() action combines Connection initiation with a first Message sent. </ins> Without a message context (as in send-basic): With a message context (as in message-props): <del> The message passed to InitiateWithIdempotentSend() is, as suggested by the name, considered to be idempotent (see msg-idempotent) regardless of declared message properties or defaults.  If protocol stacks supporting 0-RTT establishment with idempotent data are available on the Preconnection, then 0-RTT establishment may be used with the given message when establishing candidate connections.  For a non-idemponent initial message, or when the selected stack(s) do not support 0-RTT establishment, InitiateWithIdempotentSend is identical to Initiate() followed by Send(). </del> <ins> Whenever possible, a messageContext should be provided to declare the message passed to InitiateWithSend as idempotent.  This allows the transport system to make use of 0-RTT establishment in case this is supported by the available protocol stacks.  When the selected stack(s) do not support transmitting data upon connection establishment, InitiateWithSend is identical to Initiate() followed by Send(). </ins> Neither partial sends nor send batching are supported by <del> InitiateWithIdempotentSend(). </del> <ins> InitiateWithSend(). </ins> <del> The Events that may be sent after InitiateWithIdempotentSend() are equivalent to those that would be sent by an invocation of Initate() followed immediately by an invocation of Send(), with the caveat that a send failure that occurs because the Connection could not be established will not result in a SendError separate from the InitiateError signaling the failure of Connection establishment. </del> <ins> The Events that may be sent after InitiateWithSend() are equivalent to those that would be sent by an invocation of Initate() followed immediately by an invocation of Send(), with the caveat that a send failure that occurs because the Connection could not be established will not result in a SendError separate from the InitiateError signaling the failure of Connection establishment. </ins> 7.7.

Notable changes: added control over using multipath (which was a late addition to minset) added a timeout for conn. establishment, separate from the other conn. abort timeout (see ) renamed InitiateWithIdempotentSend into InitiateWithSend, and adjusted the text to recommend declaring idempotence. This addresses the minset function that goes back to TCP's send-with-SYN.
Status: NAME said "LGTM modulo tiny nits" and I think these nits are now addressed. NAME requests something more than just a boolean to enable/disable usage of multiple paths. It seems to me that this needs more discussion, but it also doesn't seem like a show-stopper for the boolean to begin with; I think we can discuss this more after landing this PR. NAME hasn't reacted (or am I missing this), but this has an ok from NAME and NAME In conclusion: I think this is good to go. I'll wait until tomorrow; unless someone speaks up by then, I'll merge this PR.
If you make it a boolean it cannot be used as a selection property, so I do not think that is a good choice. Or how should it be interpreted for the selection?
NAME what do you mean, that it should be a (binary - yes/no) Preference instead? I thought this would be more limiting but I'm fine with this as well.
NAME I meant that it should be a Preference as pointed out in the original comment by NAME I do not understand what a boolean means during selection (is it a requirement or a preference?) I also do not understand what it means in the middle of a connection. You mean you should try and use a single or several subflows for scheduling data, assuming you already have a multipath connection? I guess this is possible, but then the description needs to be more clear that this is what it means. In the appendix about minset your have "Disable MPTCP: "Parallel Use of Multiple Paths" Property." I assume this refers to the Protocol Selection phase? It does not make sense to disable or enable MPTCP in the middle of a connection I think. I guess part of how to specify the property depends on how to interpret this part from the intro to the Managing Connections section: "The application can set and query Connection Properties on a per-Connection basis.


Question: 7.6. For application-layer protocols where the Connection initiator also <del> sends the first message, the InitiateWithIdempotentSend() action combines Connection initiation with a first Message sent, provided that message is idempotent. </del> <ins> sends the first message, the InitiateWithSend() action combines Connection initiation with a first Message sent. </ins> Without a message context (as in send-basic): With a message context (as in message-props): <del> The message passed to InitiateWithIdempotentSend() is, as suggested by the name, considered to be idempotent (see msg-idempotent) regardless of declared message properties or defaults.  If protocol stacks supporting 0-RTT establishment with idempotent data are available on the Preconnection, then 0-RTT establishment may be used with the given message when establishing candidate connections.  For a non-idemponent initial message, or when the selected stack(s) do not support 0-RTT establishment, InitiateWithIdempotentSend is identical to Initiate() followed by Send(). </del> <ins> Whenever possible, a messageContext should be provided to declare the message passed to InitiateWithSend as idempotent.  This allows the transport system to make use of 0-RTT establishment in case this is supported by the available protocol stacks.  When the selected stack(s) do not support transmitting data upon connection establishment, InitiateWithSend is identical to Initiate() followed by Send(). </ins> Neither partial sends nor send batching are supported by <del> InitiateWithIdempotentSend(). </del> <ins> InitiateWithSend(). </ins> <del> The Events that may be sent after InitiateWithIdempotentSend() are equivalent to those that would be sent by an invocation of Initate() followed immediately by an invocation of Send(), with the caveat that a send failure that occurs because the Connection could not be established will not result in a SendError separate from the InitiateError signaling the failure of Connection establishment. </del> <ins> The Events that may be sent after InitiateWithSend() are equivalent to those that would be sent by an invocation of Initate() followed immediately by an invocation of Send(), with the caveat that a send failure that occurs because the Connection could not be established will not result in a SendError separate from the InitiateError signaling the failure of Connection establishment. </ins> 7.7.

Connection Properties that are not read-only can be set during pre-establishment (see {{selection-props}}), as well as on connections directly using the SetProperty action" I interpreted this as properties set during pre-establishment are selection properties, but maybe this is not the intention as they may need to be expressed differently? If they are not intended as selection properties, we are missing a selection property for multipath I guess.
NAME Ok. That's what I meant, yes - but I agree that's not covered by the description, it really is a selection preference only as it's written now. OK (though you CAN do it with the "real" API, by closing subflows, but this goes beyond the spec'd protocol, and I'm also not sure it's a good idea, especially when limited to only enabling / disabling it altogether). I would have understood this as in your first interpretation: "properties set during pre-establishment are selection properties".
NAME Closing a subflow is not the same as disabling MPTCP to me. You will still be using MPTCP, only with a single subflow. And you can certainly not open a subflow unless MPTCP is already enabled. But seems we now have a common understanding.
NAME ack, we've converged. I just pushed a commit that turns the "Parallel Use of Multiple Paths" property into a Selection property.
these are a few minor changes to apply, and properties to add (e.g. "disable MPTCP")
this is done, yes?
No. But I'm planning to do a PR to address this issue this week.
Note that this also requires closing , which I re-opened with a concrete proposal to address something from minset.
LGTM modulo tiny nitsSorry, missed this until just now. Looks fine with me, I just have a small question and my 2 cents to the multipath discussion (which we can have at a later point).


Question: 8. <del> TBD. </del> <ins> There are tradeoffs inherent in a sender sending an ACK_FREQUENCY frame to the receiver.  As such it is recommended that implementers experiment with different strategies and find those which best suit their applications and congestion controllers.  There are, however, noteworthy considerations when devising strategies for sending ACK_FREQUENCY frames. 8.1. A sender relies on receipt of acknowledgements to determine the amount of data in flight and to detect losses, e.g. when packets experience reordering, see QUIC-RECOVERY.  Consequently, how often a receiver sends acknowledgments determines how long it takes for losses to be detected at the sender. 8.2. Many congestion control algorithms have a startup mechanism during the beginning phases of a connection.  It is typical that in this period the congestion controller will quickly increase the amount of data in the network until it is signalled to stop.  While the mechanism used to achieve this increase varies, acknowledgments by the peer are generally critical during this phase to drive the congestion controller's machinery.  A sender can send ACK_FREQUENCY frames while its congestion controller is in this state, ensuring that the receiver will send acknowledgments at a rate which is optimal for the the sender's congestion controller. 8.3. Congestion controllers that are purely window-based and strictly adherent to packet conservation, such as the one defined in QUIC- RECOVERY, rely on receipt of acknowledgments to move the congestion window forward and send additional data into the network.  Such controllers will suffer degraded performance if acknowledgments are delayed excessively.  Similarly, if these controllers rely on the timing of peer acknowledgments (an "ACK clock"), delaying acknowledgments will cause undesirable bursts of data into the network. </ins> 9. TBD. <ins> 10. TBD. </ins>

I think the motivations section as-is is too long. It spends a lot of time talking about what are effectively the tradeoffs. IMO the motivations section should specify why it's useful to have the sender control the receiver's ACK frequency, and then we can have a separate section for the tradeoffs. This takes a stab at that section, lifting things from motivations and adding some new text specifically addressing the nascent stages of a connection. I also made some editorial changes to the existing text. I am happy to add any additional considerations we think might need to be called out. This attempts to
Thanks for the PR, NAME ! I like the new text you propose (I've proposed some changes), but I think you might be assuming that ACK_FREQUENCY is only used for delaying acks further. An important point that bears bringing out in the motivation is that a sender might want more frequent acks as well, for example during startup. That's worth capturing in the modified motivation section.
NAME this PR is almost done, any chance you can do another round of updates and we can get it in?
NAME sorry, I'll do some updates today.
NAME NAME I've updated the PR, I'll watch and iterate on any remaining feedback quickly this time.
thanks NAME Something about vim and the macbook pro keyboard apparently makes me incapable of spelling things properly. I want my desk keyboard back
As discussed on in the base draft, we have some confidence in a particular heuristic (default tolerance of 2 for the first 100 packets, followed by a tolerance of 10) which we know to work fairly well in multiple deployments serving "typical" Internet resources to typical users. Do we want to make that recommendation explicit, or otherwise give guidance in this extension?
I think it's a good idea to describe the values for which we have experience, while encouraging experimentation. We don't need to recommend the strategy, we just need to document it as an example strategy.
I think a section on considerations and maybe past experience would be very helpful. I think it's going to be a bit of a challenge to write, but I'm happy to take a stab if no one else wants to.
What I'd want to see is just a simple explanation of what a sender could do... I would not describe results from experience, since those are anecdotal and are going to change over time. This could be a fairly short section.


Question: 8. <del> TBD. </del> <ins> There are tradeoffs inherent in a sender sending an ACK_FREQUENCY frame to the receiver.  As such it is recommended that implementers experiment with different strategies and find those which best suit their applications and congestion controllers.  There are, however, noteworthy considerations when devising strategies for sending ACK_FREQUENCY frames. 8.1. A sender relies on receipt of acknowledgements to determine the amount of data in flight and to detect losses, e.g. when packets experience reordering, see QUIC-RECOVERY.  Consequently, how often a receiver sends acknowledgments determines how long it takes for losses to be detected at the sender. 8.2. Many congestion control algorithms have a startup mechanism during the beginning phases of a connection.  It is typical that in this period the congestion controller will quickly increase the amount of data in the network until it is signalled to stop.  While the mechanism used to achieve this increase varies, acknowledgments by the peer are generally critical during this phase to drive the congestion controller's machinery.  A sender can send ACK_FREQUENCY frames while its congestion controller is in this state, ensuring that the receiver will send acknowledgments at a rate which is optimal for the the sender's congestion controller. 8.3. Congestion controllers that are purely window-based and strictly adherent to packet conservation, such as the one defined in QUIC- RECOVERY, rely on receipt of acknowledgments to move the congestion window forward and send additional data into the network.  Such controllers will suffer degraded performance if acknowledgments are delayed excessively.  Similarly, if these controllers rely on the timing of peer acknowledgments (an "ACK clock"), delaying acknowledgments will cause undesirable bursts of data into the network. </ins> 9. TBD. <ins> 10. TBD. </ins>

NAME NAME I can take a stab at writing something and we can go from there.
Thanks, NAME !
I do think the pitfalls of e.g. should be conveyed in such "cautionary" text as well. I will submit a PR this week time permitting between interop.
Thanks, NAME


Question: 8. <del> This document does not have additional security considerations beyond those defined in QUIC and DGRAM. </del> <ins> Since this feature requires sending an HTTP/3 Settings parameter, it "sticks out".  In other words, probing clients can learn whether a server supports this feature.  Implementations that support this feature SHOULD always send this Settings parameter to avoid leaking the fact that there are applications using HTTP/3 datagrams enabled on this endpoint. </ins> 9.

As discussed at IETF 110, some MASQUE servers may prefer to avoid sticking out (i.e. they may wish to be indistinguishable from a non-MASQUE-capable HTTP/3 server). The H3_DATAGRAM SETTINGS parameter may stick out. Therefore, we should add a note about this to the Security Considerations section. A simple solution could be to encourage widespread HTTP/3 servers to always send this.


Question: %%% Key Exchange Messages This field contains the version of TLS negotiated for this <del> session.  Servers MUST select the lower of the highest supported server version and the version offered by the client in the ClientHello.  In particular, servers MUST accept ClientHello messages with versions higher than those supported and negotiate the highest mutually supported version.  For this version of the specification, the version is 0x0304.  (See backward-compatibility for details about backward compatibility.) </del> <ins> session.  Servers MUST select a version from the list in ClientHello.supported_versions extension.  A client which receives a version that was not offered MUST abort the handshake.  For this version of the specification, the version is 0x0304.  (See backward-compatibility for details about backward compatibility.) </ins> This structure is generated by the server and MUST be generated independently of the ClientHello.random.

It seems section 4.1.3 Server Hello has not been updated to reflect the new version negotiation mechanism. says "servers says "servers MUST [...] negotiate the highest mutually supported version".
Thanks, I caught a few of these on my reread yesterday too, but I probably missed some too, so keep them coming!


Question: 4. Servers MUST NOT include MD5 and SHA-1 in ServerKeyExchange messages. <del> If a client receives a MD5 or SHA-1 signature in a ServerKeyExchange message it MUST abort the connection with the illegal_parameter alert. </del> <ins> If no other signature algorithms are available (for example, if the client does not send a signature_algorithms extension), the server MUST abort the handshake with a handshake_failure alert or select a different cipher suite. </ins> 5.

cc NAME NAME NAME
I believe this I-D should still include the "update: 5246 (if approved)" header, even though we took out the 5246 OLD/NEW section. We are still proposing that 5246 be changed to require signature_algorithms extension be sent and that MD5/SHA1 never be sent. In other words, I think you can merge this PR assuming there are no conflicts.
Verifying that this is okay on list, but Daniel suggested the following change for s6: Add the following immediately bfore the OLD/NEW, i.e., right after "due to MD5 and SHA-1 being deprecated.": In Section 7.1.4.1: the following text is removed: If the client supports only the default hash and signature algorithms (listed in this section), it MAY omit the signature_algorithms extension.
Resulted in a number of changes - see .
I think you also need to update the abstract and introduction sections, as they both mention "This document updates ..." (same as URL). Will probably conflict with URL so we should merge that first.I believe this can be merged as is. I.e., don't remove the "udpates" header, change the abstract, or intro.


Question: shifting necessary in the event that there are an odd number of octets. <del> The expand_left() function outputs 16 octets, with its first argument in the most significant bits, its second argument in the least significant byte, its third argument in the second least significant byte, and zeros in all other positions.  Thus, </del> <ins> When configured with both a key, and a nonce length and server ID length that sum to any number other than 16, the server MUST follow the algorith below to encrypt the connection ID. </ins> <del> expand_right() is similar, except that the second argument is in the most significant byte, the third is in the second most significant byte, and the first argument is in the least significant bits. Therefore, </del> <ins> 4.3.2.1. </ins> <del> Similarly, truncate_left() and truncate_right() take the most significant and least significant bits, respectively, from a ciphertext.  For example, to take 28 bits of a ciphertext: </del> <ins> The 4-pass algorithm is a four-round Feistel Network with the round function being AES-ECB.  Most modern applications of Feistel Networks have more than four rounds.  The implications of this choice, which is meant to limit the per-packet compute overhead at load balancers, are discussed in distinguishing-attacks. The server concatenates the server ID and nonce into a single field, which is then split into equal halves.  In successive passes, one of these halves is expanded into a 16B plaintext, encrypted with AES- ECB, and the result XORed with the other half.  The diagram below shows the conceptual processing of a plaintext server ID and nonce into a connection ID.  'FO' stands for 'First Octet'. 4.3.2.2. Two functions are useful to define: The expand(length, pass, input_bytes) function concatenates three arguments and outputs 16 zero-padded octets. The first argument 'length' is an 8-bit integer that reports the sum of the configured nonce length and server id length in octets, and forms the most significant octet of the output.  The 'length' argument MUST NOT exceed 28. The second argument is an 8-bit integer that is the 'pass' of the algorithm, and forms the second-most significant octet of the output. The third argument is a variable-length stream of octets, which is copied into the third-most significant octet of the output and beyond.  The length of this octet stream is half the 'length', rounded up.  All remaining octets of the output are zero. For example, Similarly, truncate(input, n) returns the first n octets of 'input'. Let 'half_len' be equal to 'plaintext_len' / 2, rounded up. 4.3.2.3. </ins> The example at the end of this section helps to clarify the steps described below. The server concatenates the server ID and nonce to create <del> plaintext_CID. </del> <ins> plaintext_CID.  The length of the result in octets is plaintext_len. </ins> The server splits plaintext_CID into components left_0 and right_0 <del> of equal length, splitting an odd octet in half if necessary.  For example, 0x7040b81b55ccf3 would split into a left_0 of 0x7040b81 and right_0 of 0xb55ccf3. </del> <ins> of equal length half_len.  If plaintext_len is odd, right_0 clears its first four bits, and left_0 clears its last four bits.  For example, 0x7040b81b55ccf3 would split into a left_0 of 0x7040b810 and right_0 of 0x0b55ccf3. </ins> <del> Encrypt the result of expand_left(left_0, index)) to obtain a ciphertext, where 'index' is one octet: the two most significant bits of which are 0b00, and the six least significant bits are the length of the resulting connection ID in bytes, cid_len. </del> <ins> Encrypt the result of expand(plaintext_len, 1, left_0) using an AES-ECB-128 cipher to obtain a ciphertext. </ins> <del> XOR the least significant bits of the ciphertext with right_0 to form right_1. </del> <ins> XOR the first half_len octets of the ciphertext with right_0 to form right_1.  Steps 3 and 4 can be summarized as </ins> <del> Thus steps 3 and 4 can be expressed as "right_1 = right_0 ^ truncate_right( AES_ECB(key, expand_left(left_0, cid_len, 1)), len(right_0)) " </del> <ins> If the plaintext_len is odd, clear the first four bits of right_1. </ins> Repeat steps 3 and 4, but use them to compute left_1 by expanding <del> and encrypting right_1 with the most significant octet as the concatenation of 0b01 and cid_len, and XOR the results with </del> <ins> and encrypting right_1 with pass = 2, and XOR the results with </ins> left_0. <del> "left_1 = left_0 ^ truncate_left( AES_ECB(key, expand_right(right_1, cid_len, 2)), len(left_0)) " </del> <ins> If the plaintext_len is odd, clear the last four bits of left_1. </ins> Repeat steps 3 and 4, but use them to compute right_2 by expanding <del> and encrypting left_1 with the least significant octet as the concatenation of 0b10 and cid_len, and XOR the results with </del> <ins> and encrypting left_1 with pass = 3, and XOR the results with </ins> right_1. <del> "right_2 = right_1 ^ truncate_right( AES_ECB(key, expand_left(left_1, cid_len, 3), len(right_1)) " </del> <ins> If the plaintext_len is odd, clear the first four bits of right_2. </ins> Repeat steps 3 and 4, but use them to compute left_2 by expanding <del> and encrypting right_2 with the most significant octet as the concatenation of 0b11 ands cid_len, and XOR the results with </del> <ins> and encrypting right_2 with pass = 4, and XOR the results with </ins> left_1. <del> "left_2 = left_1 ^ truncate_left( AES_ECB(key, expand_right(right_2, cid_len, 4), len(left_1)) " </del> <ins> If the plaintext_len is odd, clear the last four bits of left_2. </ins> The server concatenates left_2 with right_2 to form the ciphertext <del> CID, which it appends to the first octet. </del> <ins> CID, which it appends to the first octet.  If plaintext_len is odd, the four least significant bits of left_2 and four most significant bits of right_2, which are all zero, are stripped off before concatenation to make the resulting ciphertext the same length as the original plaintext. 4.3.2.4. </ins> The following example executes the steps for the provided inputs. Note that the plaintext is of odd octet length, so the middle octet

Attempt to , . Examples and test vectors not yet updated. PTAL at the description. Is the algorithm accurately described Are things clearer or not
NAME Thanks for all the formatting suggestions. It's cleaned up a bit, although I wasn't able to get aasvg to work. PTAL
Correction. I got aasvg to work but it did not look good at all, probably due to user incompetence. If you would like to submit a PR after this that is prettier, I would welcome it.
Stefan Kolbl points out this problem with the 4-pass method: Indeed, there are ways to avoid ugly and error-prone bit shifting while avoiding this property. In particular, we can always use expand-left, but just padding odd-bytes with zeros to preserve byte boundaries and avoid bit-shifting.
Fixed by
Several problems here: A lot of the description relies on examples rather than normative language. The split of a CID that has an odd length produces HEX sequences with an odd number of characters, which in many circumstances will be interpreted as being (left-)padded with 4 zero bits. If that happened, then bad things would occur. You really need to retain the number of bits. Step 3 passes two arguments to , when it has three. The encryption doesn't bind to the configuration that is in use; instead the high bits of the first octet are set to 0. The formatting of the operations wraps awkwardly. The operators that this uses (^ and primarily) aren't defined. The third input to seems to increment without explanation. Given the examples, I could no doubt work this all out satisfactorily, but that shouldn't be necessary.
Fixed by
A lot.
Yes, the new text seems clear, and correct.


Question: 4.6. <del> The encrypted payload of an OHTTP request and response is a binary HTTP message BINARY.  The and agree on this encrypted payload type by specifying the media type "message/bhttp" in the HPKE info string and HPKE export context string for request and response encryption, respectively. </del> <ins> The encrypted payload of an Oblivious HTTP request and response is a binary HTTP message BINARY.  The and agree on this encrypted payload type by specifying the media type "message/bhttp" in the HPKE info string and HPKE export context string for request and response encryption, respectively. </ins> Future specifications may repurpose the encapsulation mechanism described in this document.  This requires that the specification

From NAME Interesting that this is the first time OHTTP appear in the text, excluding pseudocode and mediatype - please expand (or define somewhere else, for example in terminology).


Question: included in this candidate collection.  However, disclosure of these addresses has privacy implications.  This document describes a way to share local IP addresses with other clients while preserving client <del> privacy.  This is achieved by obfuscating IP addresses with </del> <ins> privacy.  This is achieved by concealing IP addresses with </ins> dynamically generated Multicast DNS (mDNS) names. 1.

On line 421: "that this specification is designed to hide". Could edit that as well.
My take is that we don't need to use the same term in every case, but the terms should have the same meaning. conceal and hide are fairly synonymous, but conceal and obfuscate have slightly different meanings.
Does it obfuscate, conceal, or obscure local IP addresses? My vote is for conceal.
Conceal/concealment sgtm.
As noted in , we don't need to use the same term in every case, but the terms should have the same meaning. conceal and hide are fairly synonymous, but conceal and obfuscate have slightly different meanings.


Question: instead continues to use the peer's "Ack-Eliciting Threshold" and "max_ack_delay" thresholds for sending acknowledgements. <del> 6.2. </del> <ins> 7.2. </ins> As specified in Section 13.2.1 of QUIC-TRANSPORT, an endpoint SHOULD immediately acknowledge packets marked with the ECN Congestion Experienced (CE) codepoint in the IP header.  Doing so reduces the peer's response time to congestion events. <del> 6.3. </del> <ins> 7.3. </ins> For performance reasons, an endpoint can receive incoming packets from the underlying platform in a batch of multiple packets.  This

by adding a one byte IMMEDIATE_ACK frame.
editorial nit: my preference would be for frame diagrams to use the notation in QUIC transport. I see that ACK_FREQUENCY is defined using ASCII art, so perhaps you want to consider a separate follow up PR to switch styles after this lands.
Thanks Lucas, I filed to update them.
They currently use ascii art. Will write this up once is merged.
sgtm, thanks!
When sending a PTO packet, a sender wants to induce an immediate ACK. The only trick I know to induce such an ACK is intentionally skip the packet number. However, the problem of that approach is that it relies on the receiver not ignoring reorders. When an ACKFREQUENCY frame previously sent had set the bit, then it become impossible for a sender to induce an immediate ACK when sending a PTO packet. At the moment, the only solution is to bundle an ACK_FREQUENCY packet in each PTO packet, but that seems like a bit of unnecessary overhead to me. Should we have a dedicated frame for inducing immediate ACKs instead?
That's an option. Another option is to revisit the max_reordering idea discussed in . If the max reordering was 5, then you could skip 5 PNs. I do feel like it'd be nice to allow specifying an int for max reordering, since that matches up with adaptive packet threshold loss detection, but as I expressed in , I think getting the details right are deceptively difficult, so I'm torn.
This does seem like a real problem. I like the idea of a single "ELICIT_ACK" type frame. With one byte a sender could effectively mark its PTOs ensuring they get an ACK without relying on the trick. An explicit frame is also easier to implement for the sender than the packet number skipping.
There's quite a bit of discussion on this on the tcpm mailing list at the moment, ie: URL I'm increasingly thinking it's worth using an unused protected bit in the header for this. It'd end up competing with the 2-bit packet loss measurements, but given those are experimental and may never be widely deployed, I think it might be worth it. For example, I believe this could allow an implementation to not include maxackdelay in PTO if it set the "ACK-pull"(or whatever it's called) bit on the final packet.


Question: instead continues to use the peer's "Ack-Eliciting Threshold" and "max_ack_delay" thresholds for sending acknowledgements. <del> 6.2. </del> <ins> 7.2. </ins> As specified in Section 13.2.1 of QUIC-TRANSPORT, an endpoint SHOULD immediately acknowledge packets marked with the ECN Congestion Experienced (CE) codepoint in the IP header.  Doing so reduces the peer's response time to congestion events. <del> 6.3. </del> <ins> 7.3. </ins> For performance reasons, an endpoint can receive incoming packets from the underlying platform in a batch of multiple packets.  This

That already seems possible if more than the threshold number of ack-eliciting packets are outstanding.
I've thought more about this, and I think most of the time a 1-byte frame would be acceptable, but it definitely adds some implementation complexity, so I'd be curious which design others prefer? If we can decide, then I'll be happy to write a PR(or NAME can). Besides PTO, a use case would be making the last packet before becoming app-limited elicit an immediate ACK. This could allow skipping maxackdelay for all PTOs(see ), though always doing it could be a bit much in some cases. For example, browsers commonly send a series of requests, but to the transport it seems app-limited between them, because it doesn't know the browser has another request to send. It might be useful for 'chirping' as well, but I've never tried that, so it's mostly speculation.
We don't currently have any intention of deploying them either, and I think that's unlikely to change. I haven't seen a lot of good evidence that they are terribly helpful, and content providers don't seem to have a good incentive for implementing it. For us at least, the difference in complexity for a frame versus a bit in the header is negligible. A frame is actually be slightly easier to implement and losing a byte here and there isn't so bad.
I strongly prefer using the header bit. Although it will be a bit more work to implement, the fact that I won't end up with a 1-byte STREAM frame that I have to split off at the end of the packet will be worth the effort.
Is testimony of network operators not taken as evidence? I remember a line of people, from different companies -- BT, ATT, and so on, at IETF 101 practically begging for some information in QUIC packets to be exposed for monitoring and troubleshooting.
I do not see anyone propose a 1-byte STREAM frame. I believe what is meant is a new frame type. If anything, using a new frame type to elicit an ACK is easier than using a header bit, as it involves fewer parts of the code to change.
Nobody is proposing a 1-byte STREAM frame (you can't just make up stream data anyway). The problem is that a new frame would consume bytes (or probably one byte) in the packet payload.