Question: mean skipping rounds, so if PSK is not in use Early Secret will still be HKDF-Extract(0, 0).  For the computation of the binder_secret, the label is "external psk binder key" for external PSKs (those <del> provisioned outside of TLS) and "resumption psk binder key" for resumption PSKs (those provisioned as the resumption master secret of a previous handshake).  The different labels prevent the substitution of one type of PSK for the other. </del> <ins> provisioned outside of TLS) and "res binder" for resumption PSKs (those provisioned as the resumption master secret of a previous handshake).  The different labels prevent the substitution of one type of PSK for the other. </ins> There are multiple potential Early Secret values depending on which PSK the server ultimately selects.  The client will need to compute

Per mailing list discussion, this allows us to have every HKDF-Expand just have one hash block of info. NAME would love your feedback.
Shouldn't "TLS 1.3, " be shortened to "tls13 "? Without that, several of the labels would seem to blow blocks. Also, "derived secret" seems unchanged, and is too long to fit into a block, even with "tls13 " prefix.
Oops. Good catch. Script fail.
NAME fixed?
Yeah, I'll add a note. I still have an issue for the ChangeLog so I will add this as well
Also, minimum label size looks to be still 10, presumably should be 7 with 6-byte prefix (as it 10 with 9-byte prefix).


Question: filter expression: Its only argument is an instance of "ValueType" (possibly taken from <del> a singular path as in the example above).  The result also is an </del> <ins> a singular query as in the example above).  The result also is an </ins> instance of "ValueType": an unsigned integer or "Nothing". If the argument value is a string, the result is the number of

XPath terminology is a bit weird, because XPath has a somewhat competing standard XQuery... XPath is based on DSSSL, which had a complex expression language for building paths in the XML trees that was based on the Scheme language. (Which is the experience that makes me hesitant just jumping headlong into another expression language...)
LGTM with that change. Thanks!


Question: as a result of racing multiple transports or as part of TCP Fast Open. <ins> Final: when this is true, it means that a transport connection can be closed immediately after its transmission. </ins> Corruption Protection Length: when this is set to any value other than -1, it limits the required checksum in protocols that allow limiting the checksum length (e.g.  UDP-Lite). <del> Immediate Acknowledgement: this informs the implementation that the sender intends to execute tight control over the send buffer, and therefore wants to avoid delayed acknowledgements.  In case of SCTP, a request to immediately send acknowledgements can be implemented using the "sack-immediately flag" described in Section 4.2 of RFC8303 for the SEND.SCTP primitive. Instantaneous Capacity Profile: when this is set to "Interactive/ Low Latency", the Message should be sent immediately, even when this comes at the cost of using the network capacity less efficiently.  For example, small messages can sometimes be bundled to fit into a single data packet for the sake of reducing header overhead; such bundling should not be used.  For example, in case of TCP, the Nagle algorithm should be disabled when Interactive/ Low Latency is selected as the capacity profile.  Scavenger/Bulk can translate into usage of a congestion control mechanism such as LEDBAT, and/or the capacity profile can lead to a choice of a DSCP value as described in I-D.ietf-taps-minset). [Note: See also send-params-non-consensus for additional Send Parameters under discussion.] </del> <ins> Transmission Profile: TBD - because it's not final in the API yet. Old text follows: when this is set to "Interactive/Low Latency", the Message should be sent immediately, even when this comes at the cost of using the network capacity less efficiently.  For example, small messages can sometimes be bundled to fit into a single data packet for the sake of reducing header overhead; such bundling should not be used.  For example, in case of TCP, the Nagle algorithm should be disabled when Interactive/Low Latency is selected as the capacity profile.  Scavenger/Bulk can translate into usage of a congestion control mechanism such as LEDBAT, and/ or the capacity profile can lead to a choice of a DSCP value as described in I-D.ietf-taps-minset). Singular Transmission: when this is true, the application requests to avoid transport-layer segmentation or network-layer fragmentation.  Some transports implement network-layer fragmentation avoidance (Path MTU Discovery) without exposing this functionality to the application; in this case, only transport- layer segmentation should be avoided, by fitting the message into a single transport-layer segment or otherwise failing.  Otherwise, network-layer fragmentation should be avoided--e.g. by requesting the IP Don't Fragment bit to be set in case of UDP(-Lite) and IPv4 (SET_DF in RFC8304). </ins> 5.1.1.2.

Several small updates, mostly to clean things up a bit, and align property names and such.
NAME - I think you're wrong: my understanding (and also the way the text is written - otherwise we'd have to change it in the API draft) was that Connection Properties can (and should) also be set on Preconnections, to give as much input as possible for Connection establishment. In the API draft, the Selection Properties in Section 5.2 can only be used on Preconnections: you can't ask for congestion control after establishment. You can't say that you'd rather have multistreaming support after establishment. But that doesn't exclude Connection properties from being usable earlier. Required minimum checksum coverage could influence choosing UDP-Lite vs. UDP. Bounds on Send or Receive Rate could influence the interface choice. The capacity profile could influence various things (and no, there isn't a matching Selection Property now - there is a per-Message override). So... I think that either you're wrong, or I'm missing something and the API draft heavily lags behind a decision that was made. I hope not!
NAME The API drafts says: I interpret this as only the Selection Properties influence selection and the Connection properties are used to further configure the connections according to user preferences. Otherwise what is the difference between them?
If you interpret it as you do, I think the text isn't clear enough (indeed it isn't super clear - in particular, "eventually established" is misleading IMO). Though, note that it says that Connection properties can also be used later. Regarding the difference between them: Selection Properties only make sense for Preconnections.
NAME - sorry lost this thread. But I saw that you have started cleaning up some Connection properties that had mixed Connection and Selection properties up in the API draft. Does it mean that we are now in synch and agree that only Selection properties are used in the selection and Connection properties are used for configuration (both during establisment and also after the connection setup).
NAME the other PR means nothing about what I said here: it only tried to address issue which is about a wording inconsistency in a specific property. You say that Connection properties can also be used during establishment - if you agree with allowing this, then why not allow to configure them as early as possible and allow them to influence selection?


Question: as a result of racing multiple transports or as part of TCP Fast Open. <ins> Final: when this is true, it means that a transport connection can be closed immediately after its transmission. </ins> Corruption Protection Length: when this is set to any value other than -1, it limits the required checksum in protocols that allow limiting the checksum length (e.g.  UDP-Lite). <del> Immediate Acknowledgement: this informs the implementation that the sender intends to execute tight control over the send buffer, and therefore wants to avoid delayed acknowledgements.  In case of SCTP, a request to immediately send acknowledgements can be implemented using the "sack-immediately flag" described in Section 4.2 of RFC8303 for the SEND.SCTP primitive. Instantaneous Capacity Profile: when this is set to "Interactive/ Low Latency", the Message should be sent immediately, even when this comes at the cost of using the network capacity less efficiently.  For example, small messages can sometimes be bundled to fit into a single data packet for the sake of reducing header overhead; such bundling should not be used.  For example, in case of TCP, the Nagle algorithm should be disabled when Interactive/ Low Latency is selected as the capacity profile.  Scavenger/Bulk can translate into usage of a congestion control mechanism such as LEDBAT, and/or the capacity profile can lead to a choice of a DSCP value as described in I-D.ietf-taps-minset). [Note: See also send-params-non-consensus for additional Send Parameters under discussion.] </del> <ins> Transmission Profile: TBD - because it's not final in the API yet. Old text follows: when this is set to "Interactive/Low Latency", the Message should be sent immediately, even when this comes at the cost of using the network capacity less efficiently.  For example, small messages can sometimes be bundled to fit into a single data packet for the sake of reducing header overhead; such bundling should not be used.  For example, in case of TCP, the Nagle algorithm should be disabled when Interactive/Low Latency is selected as the capacity profile.  Scavenger/Bulk can translate into usage of a congestion control mechanism such as LEDBAT, and/ or the capacity profile can lead to a choice of a DSCP value as described in I-D.ietf-taps-minset). Singular Transmission: when this is true, the application requests to avoid transport-layer segmentation or network-layer fragmentation.  Some transports implement network-layer fragmentation avoidance (Path MTU Discovery) without exposing this functionality to the application; in this case, only transport- layer segmentation should be avoided, by fitting the message into a single transport-layer segment or otherwise failing.  Otherwise, network-layer fragmentation should be avoided--e.g. by requesting the IP Don't Fragment bit to be set in case of UDP(-Lite) and IPv4 (SET_DF in RFC8304). </ins> 5.1.1.2.

What's bad about having more information available that can guide the selection process?
NAME the problem is that the Connection properties are not expressed in a way suitable for selection. If they should also be used for Selection they would have to be reworked to be of type Preference. Otherwise I do not know what they mean for selection. What does it mean if I pick say a particular connection group transmission scheduler? Is it required or preferred? Most connection properties also do not look very useful to me for selection so in case there are some we need I think it would be simpler to just define a matching selection property.
NAME we're only discussing whether it's allowed to use them as additional input or not. I agree, some (like the scheduler choice) don't seem useful, but some do... generally we may not have good guidance on how they should be used by an implementation, but giving the system freedom to use as many inputs as possible is probably a good thing. Regarding the type, require/prefer//ignore/avoid/prohibit obviously works fine for a "wishlist" of boolean character: having something, or not having it. The selection properties are generally like that - except "Interface Instance or Type" and "Provisioning Domain Instance or Type" which are, well... wishlist-collections. Consider the capacity profile. Surely configuring this early can be useful input - e.g. if someone picks low latency / interactive, you may even want to put this traffic on a specific network interface! But if you'd want to make a copy of the capacity profile as a "proper" selection property, how would you do it? Apply require/prefer/ignore/avoid/prohibit for each of its values? Then I could say "prefer" low latency/non-interactive but "avoid" low latency/non-interactive, which would surely be odd. Apply the qualifier to the whole thing? Then it's about, e.g. "avoiding" to use a capacity profile at all. That's odd as well. I think it's in the nature of the current selection properties that they merely say "I want to be able to do this, and this is how important it is to me", which is different from configuring something. That's also why, as written, they simply wouldn't work for later connection configuration.


Question: as a result of racing multiple transports or as part of TCP Fast Open. <ins> Final: when this is true, it means that a transport connection can be closed immediately after its transmission. </ins> Corruption Protection Length: when this is set to any value other than -1, it limits the required checksum in protocols that allow limiting the checksum length (e.g.  UDP-Lite). <del> Immediate Acknowledgement: this informs the implementation that the sender intends to execute tight control over the send buffer, and therefore wants to avoid delayed acknowledgements.  In case of SCTP, a request to immediately send acknowledgements can be implemented using the "sack-immediately flag" described in Section 4.2 of RFC8303 for the SEND.SCTP primitive. Instantaneous Capacity Profile: when this is set to "Interactive/ Low Latency", the Message should be sent immediately, even when this comes at the cost of using the network capacity less efficiently.  For example, small messages can sometimes be bundled to fit into a single data packet for the sake of reducing header overhead; such bundling should not be used.  For example, in case of TCP, the Nagle algorithm should be disabled when Interactive/ Low Latency is selected as the capacity profile.  Scavenger/Bulk can translate into usage of a congestion control mechanism such as LEDBAT, and/or the capacity profile can lead to a choice of a DSCP value as described in I-D.ietf-taps-minset). [Note: See also send-params-non-consensus for additional Send Parameters under discussion.] </del> <ins> Transmission Profile: TBD - because it's not final in the API yet. Old text follows: when this is set to "Interactive/Low Latency", the Message should be sent immediately, even when this comes at the cost of using the network capacity less efficiently.  For example, small messages can sometimes be bundled to fit into a single data packet for the sake of reducing header overhead; such bundling should not be used.  For example, in case of TCP, the Nagle algorithm should be disabled when Interactive/Low Latency is selected as the capacity profile.  Scavenger/Bulk can translate into usage of a congestion control mechanism such as LEDBAT, and/ or the capacity profile can lead to a choice of a DSCP value as described in I-D.ietf-taps-minset). Singular Transmission: when this is true, the application requests to avoid transport-layer segmentation or network-layer fragmentation.  Some transports implement network-layer fragmentation avoidance (Path MTU Discovery) without exposing this functionality to the application; in this case, only transport- layer segmentation should be avoided, by fitting the message into a single transport-layer segment or otherwise failing.  Otherwise, network-layer fragmentation should be avoided--e.g. by requesting the IP Don't Fragment bit to be set in case of UDP(-Lite) and IPv4 (SET_DF in RFC8304). </ins> 5.1.1.2.

Connection properties really are about configuring something, but I still say that being able to use them as early input is good. I agree that the implementation isn't super clear as they don't come with a require/prefer/... etc. qualifier, but then we just offer some freedom to implementers.
NAME I just pushed a commit that updates the selection and connection properties text, removing "connection" almost everywhere, but adding a disclaimer in the beginning that says that connection properties should be configured as early as possible because they can influence decisions made by the implementation, and "In the remainder of this document, we only refer to Selection Properties because they are the more typical case." Frankly I'm not sure this is better... but it does remove most of the "selection and connection" double mentions that you pointed out.
Fixed up branch building and resolved merge conflicts. I'll merge this in later today before the posting deadline.
Cool thanks! Sorry if I messed something up
As discussed in
Thank you for updating this – looks good! just needs s/send-params/msg-properties/ and merging


Question: characteristics as input for the switching decision or the congestion controller on the new path. <ins> Only the client can actively migrate.  However, servers can indicate during the handshake that they prefer to transfer the connection to a different address after the handshake, e.g. to move from an address that is shared by multiple servers to an address that is unique to the server instance.  The server can provide an IPv4 and an IPv6 address in a transport parameter during the TLS handshake and the client can select between the two if both are provided.  See also Section 9.6 of QUIC. </ins> 8. QUIC connections are closed either by expiration of an idle timeout,

note: when merged.
We should probably make it clear what the application can do here (SPA for servers; maybe intentional migration for clients?) I'm not sure if migration is transparent to client applications or not.
The client application might have some knowledge if it's behind a NAT or not and as such might want to indicate to use Conn ID or not. We can make that more explicit in the text.
I did some small edits on the text in the connection migration section but NAME maybe you had something more in mind and want to propose more text?
This whole section should then also be moved to after the Conn ID section.
I like the move of text to the manageability draft. If it were me, I'd move "Server-Generated Connection ID" as well, as I don't think apps need to worry about it, but it's not a big deal. I think adding text about server preferred address is probably more important for this draft.
Added some more text in
NAME we think the current state of the draft addresses this issue; could you check and close this issue if so?


Question: From the client's perspective, a WebTransport session is established when the client receives a 200 response.  From the server's perspective, a session is established once it sends a 200 response. <del> Both endpoints MUST NOT open any streams or send any datagrams on a given session before that session is established.  WebTransport over HTTP/3 does not support 0-RTT. </del> <ins> WebTransport over HTTP/3 does not support 0-RTT. </ins> 3.4.

.
cc NAME NAME
Looks great!
For a simple application that wants to send "hello world" over a WebTransport stream, it would take a minimum of 2.5 round trips for the data to arrive on the server. This is still an improvement over WebSockets but I'm wondering if we could do better. If the client is able to create streams prior to receiving the CONNECT response, then it would remove a round trip. The server would need to buffer any data received on streams associated with an unknown WebTransport session. If the server responds with a non-200 status code, then these streams are discarded. I believe 0-RTT is disabled for WebTransport because CONNECT is not idempotent and would be subject to replay attacks. An idempotent CONNECT would remove a round trip when 0-RTT is used... although I'm not sure this is a good idea.
I think this is a reasonable optimization
The client requirement is odd in comparison to MASQUE / CONNECT-UDP which says "client can risk sending datagrams before getting a 200 response, a different response means that datagrams will be discarded". What is the motivation for the requirement in WebTransport? If you need some kind of ordering guarantees, then stream IDs provide that.
Discussed at IETF 110. There were no objections to buffering (with some limits), so I think we should go ahead and add it.
After the client initiates the WebTransport session by sending a CONNECT request, the server sends a 200 response and is free to create streams. This means that a server-initiated stream may arrive prior to the CONNECT response. Is the client able to infer that the session was successfully established, or does the client need to buffer this stream until it receives a proper response?
Since there are no ordering guarantees across streams on the receiver side, I'd say you have to buffer until the 200 is processed.
I agree with Lucas here. We also had a similar problem in QuicTransport (server has to buffer streams before checking the origin), and we handled it by buffering.
Discussed at IETF 110. There were no objections to buffering (with some limits), so I think we should go ahead and add it.


Question: codepoint in the IP header SHOULD be acknowledged immediately, to reduce the peer's response time to congestion events. <del> 4.2. </del> <ins> 5.2. </ins> For performance reasons, an endpoint can receive incoming packets from the underlying platform in a batch of multiple packets.  This

This PR changes a few things: Introduces a TP for negotiating extension use Changes to Makes the fields required Specifies invalid values
I'm merging this, let's address issues in later PRs.
I think it'll be easier to make both parameters required. Not doing so saves 1 to 2 bytes, which is really not much in a frame I expect will be sent a few times a connection. Also, I think 0 should be an invalid value for both params, and 1 should be invalid for the number of packets, though I can see someone arguing that point.
addresses these issues, with the exception that 1 is allowed for packet tolerance. I think that's actually useful for some startup schemes, so we shouldn't disallow it.


Question: derivation, as per Section 5.4.3 and Section 7.2.1 of I-D.ietf- lake-edhoc, respectively. <ins> If the applicability statement used in the EDHOC session specifies that EDHOC message_4 shall be sent, the Server MUST stop the EDHOC processing and consider it failed, as due to a client error. </ins> Extract the OSCORE ciphertext from the payload of the EDHOC + OSCORE request, as the value of the second CBOR byte string in the CBOR sequence.

Clean-up after URL As the content-from-edhoc branch seems to be the most up-to-date one (in which the parts changed are introduced in the first place), this builds on , and only the latest commit is actually relevant.
Compared to the original bstridentifier mapping, this is a different int-to-bstr mapping, but one that's most likely efficient to implement. I have not made any statement on the efficiencies, but some guidance we could give is that from a coding density point of view, numeric Cx should only be used with -24..23; for all other values, doing it in a bstr is just as good and saves a byte in OSCORE. (In fact we may want to make that normative, so that only the single-byte case needs to be implemented where this needs explicit implementation).


Question: 4.2.4. <ins> The direction method returns the last value passed into setDirection. If setDirection has never been called, it returns the direction the transceiver was initialized with. 4.2.5. The currentDirection method returns the last negotiated direction for the transceiver's associated m= section.  More specifically, it returns the RFC3264 directional attribute of the associated m= section in the last applied answer, with "send" and "recv" directions reversed if it was a remote answer.  For example, if the directional attribute for the associated m= section in a remote answer is "recvonly", currentDirection returns "sendonly". If an answer that references this transceiver has not yet been applied, or if the transceiver is stopped, currentDirection returns null. 4.2.6. </ins> The setCodecPreferences method sets the codec preferences of a transceiver, which in turn affect the presence and order of codecs of the associated m= section on future calls to createOffer and

This distinguishes between the direction which was last set via setDirection (which simply affects offer/answer generation) from the direction that was negotiated, which affects whether a transceiver can send/recv media. Addresses issue .
According to WebRTC 1.0 Section 5.4 setDirection() does not take effect immediately: "The setDirection method sets the direction of the RTCRtpTransceiver. Calls to setDirection() do not take effect immediately. Instead, future calls to createOffer and createAnswer mark the corresponding media description as sendrecv, sendonly, recvonly or inactive as defined in [JSEP] (section 5.2.2. and section 5.3.2.). Calling setDirection() sets the negotiation-needed flag." My interpretation of the above is that setDirection immediately sets the transceiver.direction attribute, but that the "current direction" (distinct from the direction attribute) is only changed by calls to setLocal/setRemoteDescription. I would like to suggest that JSEP indicate precisely when the "current direction" changes. My reading of JSEP is that this is determined from the currentLocalDescription and currentRemoteDescription. For example: The direction provided in the currentLocalDescription (e.g. the "current direction") is "sendrecv" and setDirection("recvonly") is called. Since setDirection does not change the direction in currentLocalDescription, the RtpSender does not stop sending. createOffer() is called. A "recvonly" offer is generated. setLocalDescription(RecvOnlyOffer) is called. Now the direction in pendingLocalDescription changes to "recvonly", but the direction in currentLocalDescription is still "sendrecv", so the RtpSender does not stop sending. setRemoteDescription(SendOnlyAnswer) is called. Now the direction in currentLocalDescription is "recvonly", so the RtpSender will stop sending.
Bernard's description makes sense to me; currentLocal/Remote indicate the current direction state.
Fixed by


Question: When generating a routable connection ID, the server writes arbitrary bits into its nonce octets, and its provided server ID into the server ID octets.  Servers MAY opt to have a longer connection ID <del> beyond the nonce and server ID.  The nonce and additional bits MAY encode additional information, but SHOULD appear essentially random to observers. </del> <ins> beyond the nonce and server ID.  The additional bits MAY encode additional information, but SHOULD appear essentially random to observers. If the decrypted nonce bits increase monotonically, that guarantees that nonces are not reused between connection IDs from the same server. </ins> The server encrypts the server ID using exactly the algorithm as described in triple-stream-cipher-load-balancer-actions, performing

I will probably delete the Stream Cipher algorithm entirely, but consider this an intermediate step.
Merging to enable the next round of edits


Question: The certificate and signing key to be used. <del> A Handshake Context based on the hash of the handshake messages </del> <ins> A Handshake Context based on the transcript of the handshake messages </ins> A base key to be used to compute a MAC key.

The handshake context here is just the transcript of the handshake messages, not the hash of the transcript. The language makes it seem like the authentication messages are Hash(Hash(handshake messages) + Certificate), etc.


Question: both were then selected as the default TCP congestion controllers in Linux, and both were deployed globally. <del> The point mentioned in tcp-behavior about TCP congestion controllers being implemented in operating system kernels is different with QUIC. Although QUIC can be implemented in operating system kernels, one of the design goals when this work was chartered was "QUIC is expected to support rapid, distributed development and testing of features," and to meet this expectation, many implementers have chosen to implement QUIC in user space, outside the operating system kernel, and to even distribute QUIC libraries with their own applications. It is worth noting that streaming operators using HTTP/3, carried over QUIC, can expect more frequent deployment of new congestion controller behavior than has been the case with HTTP/1 and HTTP/2, carried over TCP. </del> <ins> The point mentioned in reliable-behavior about TCP congestion controllers being implemented in operating system kernels is different with QUIC.  Although QUIC can be implemented in operating system kernels, one of the design goals when this work was chartered was "QUIC is expected to support rapid, distributed development and testing of features," and to meet this expectation, many implementers have chosen to implement QUIC in user space, outside the operating system kernel, and to even distribute QUIC libraries with their own applications.  It is worth noting that streaming operators using HTTP/3, carried over QUIC, can expect more frequent deployment of new congestion controller behavior than has been the case with HTTP/1 and HTTP/2, carried over TCP. </ins> It is worth considering that if TCP-based HTTP traffic and UDP-based HTTP/3 traffic are allowed to enter operator networks on roughly

…transport protocols Also tighten up description of the assumed protocol stack in (what is now) Section 6.1. Note that the UDP and TCP sections have been flipped in order, to improve section flow and clarity.
NAME - If you have a moment before our call on Friday to take a look at this PR, I'd appreciate it. I think it's important to to get that right, in order to address both the INTDIR and TSVART reviews.
From NAME As a bit of transport commentary, I don't find the setup of Section 6 compelling. While UDP is a transport in a technical sense, for the purpose of media, it is almost always a layer upon which the protocol doing the congestion control work runs. To that end, QUIC is just another more standardized case of this, just like SCTP over UDP. Rather than talking about "UDP's behavior" vs "TCP's behavior", I suggest talking about how applications over UDP for media behave vs applications over TCP for media behave.
NAME - I need to look at this more closely. I understand your point about UDP, but (because UDP is not a real transport layer, while TCP and QUIC are), I suspect (without looking closely yet) I'm going to be making sure that I explain this more clearly, without trying to explain the behavior(s) of applications running over TCP and QUIC. As an aside, I'm trying to make this clearer in drafts I'm targeting forwards Media Over QUIC/MOQ, so I actually DO believe you ... Please await results.
A +1 from NAME 's review (URL): Section 6. Evolution of Transport Protocols and Transport Protocol Behaviors I really wonder whether UDP vs. TCP vs. QUIC is actually the relevant distinction. What may actually matter are the transport services provided by the protocol stack (e.g., RFC 8095). I fully agree to a related comment in the INTDIR review.
After looking at this issue. I agree with both NAME and NAME that the emphasis should be on the interaction between (see new section describing this) media transport protocols and the transport services provided by underlying transport protocols. I'm moving the formerly-UDP section below the formerly-TCP section, because it's easier to describe what UDP is NOT doing after describing what TCP IS doing.


Question: both were then selected as the default TCP congestion controllers in Linux, and both were deployed globally. <del> The point mentioned in tcp-behavior about TCP congestion controllers being implemented in operating system kernels is different with QUIC. Although QUIC can be implemented in operating system kernels, one of the design goals when this work was chartered was "QUIC is expected to support rapid, distributed development and testing of features," and to meet this expectation, many implementers have chosen to implement QUIC in user space, outside the operating system kernel, and to even distribute QUIC libraries with their own applications. It is worth noting that streaming operators using HTTP/3, carried over QUIC, can expect more frequent deployment of new congestion controller behavior than has been the case with HTTP/1 and HTTP/2, carried over TCP. </del> <ins> The point mentioned in reliable-behavior about TCP congestion controllers being implemented in operating system kernels is different with QUIC.  Although QUIC can be implemented in operating system kernels, one of the design goals when this work was chartered was "QUIC is expected to support rapid, distributed development and testing of features," and to meet this expectation, many implementers have chosen to implement QUIC in user space, outside the operating system kernel, and to even distribute QUIC libraries with their own applications.  It is worth noting that streaming operators using HTTP/3, carried over QUIC, can expect more frequent deployment of new congestion controller behavior than has been the case with HTTP/1 and HTTP/2, carried over TCP. </ins> It is worth considering that if TCP-based HTTP traffic and UDP-based HTTP/3 traffic are allowed to enter operator networks on roughly

I'm also moving one paragraph into the formerly-TCP section from Section 6, because it is specific to ABR strategies that assume a reliable transport. More news to come, when I create a PR for this issue ...
We think is now mergrable. Reviewer: Michael Scharf Review result: Ready with Issues This document has been reviewed as part of the transport area review team's ongoing effort to review key IETF documents. These comments were written primarily for the transport area directors, but are copied to the document's authors and WG to allow them to address any issues raised and also to the IETF discussion list for information. When done at the time of IETF Last Call, the authors should consider this review as part of the last-call comments they receive. Please always CC EMAIL if you reply to or forward this review. This informational document surveys network and transport protocol issues that affect quality of experience for streaming applications, in particular video. The overview covers many topics across different technologies. Readers may only be familiar with a subset of these topics and could therefore learn quite a bit from this kind of tutorial. Nonetheless, it remains somewhat unclear what the actual objective of some of the text is. For some topics, quite a bit of technical background is provided, but the discussion is not really comprehensive. In many sections, the document neither derives technical challenges, nor system/protocol requirements, nor practical usage guidance. It is just a kind of tutorial. Quite a bit of text also presents ongoing IETF work, and an RFC with this scope may thus get outdated soon. Section 6.2 deals with topics owned by TCPM. In similar past documents, I have asked for a TCPM presentation prior to an IETF last call in order to ensure that owners of running code are in the loop. I believe this strategy has worked well in the past. Having said this, as TSV-ART reviewer I don't strongly disagree with a publication. All these issues may just be OK for an informational RFC. Some more specific comments: Section 3.2.1. Recognizing Changes from an Expected Baseline This section apparently assumes relatively static path properties, e.g., fixed network connectivity. It would be more useful to analyze the impact of Wifi and 4G/5G networks in one place.


Question: both were then selected as the default TCP congestion controllers in Linux, and both were deployed globally. <del> The point mentioned in tcp-behavior about TCP congestion controllers being implemented in operating system kernels is different with QUIC. Although QUIC can be implemented in operating system kernels, one of the design goals when this work was chartered was "QUIC is expected to support rapid, distributed development and testing of features," and to meet this expectation, many implementers have chosen to implement QUIC in user space, outside the operating system kernel, and to even distribute QUIC libraries with their own applications. It is worth noting that streaming operators using HTTP/3, carried over QUIC, can expect more frequent deployment of new congestion controller behavior than has been the case with HTTP/1 and HTTP/2, carried over TCP. </del> <ins> The point mentioned in reliable-behavior about TCP congestion controllers being implemented in operating system kernels is different with QUIC.  Although QUIC can be implemented in operating system kernels, one of the design goals when this work was chartered was "QUIC is expected to support rapid, distributed development and testing of features," and to meet this expectation, many implementers have chosen to implement QUIC in user space, outside the operating system kernel, and to even distribute QUIC libraries with their own applications.  It is worth noting that streaming operators using HTTP/3, carried over QUIC, can expect more frequent deployment of new congestion controller behavior than has been the case with HTTP/1 and HTTP/2, carried over TCP. </ins> It is worth considering that if TCP-based HTTP traffic and UDP-based HTTP/3 traffic are allowed to enter operator networks on roughly

Some of this follows later in sections 3.2.1 and Yet, the split between these three sections is unclear. Having a discussion about today's Internet path characteristics and the dynamics at one place could be more useful. The text could also better distinguish between what matters to endpoints and considerations relevant only for middleboxes (such as passive monitors). Section 3.3 Path Requirements The statement "to find the bandwidth requirements for a router on the delivery path" may assume that the bottleneck on the path will be routers. Yet, on a path the bottlenecks could also be a link layer device (e.g., an Ethernet Switch, a Wifi access point, etc.). RFC 6077 (specifically Section 3.1.3) also explains that issue. A better wording may be "to find the bandwidth requirements for a delivery path". Section 3.6. Unpredictable Usage Profiles / Section 3.7. Extremely Unpredictable Usage Profiles I am not fully convinced by the distinction between "unpredictable" and "extremely unpredictable". To me, these two sections could be merged and maybe also be shortened. More specifically, Section 3.7 lists a lot of statistics from the past. What is IMHO a bit missing in Section 3.7 are actual operational considerations. For instance, are there any lessons learnt for the future? Note that Section 3.6 has a reasonable conclusion at the end. Section 4. Latency Considerations and Section 4.1. Ultra Low-Latency I am surprised by the definition "ultra low-latency (less than 1 second)", as well as some of the other numbers. For other real-time communication use cases, "ultra low-latency" would probably imply a latency requirement of the order of one millisecond. For instance, isochronous traffic for motion control in industrial networks may require a latency of 1 ms, and such "ultra-low latency" requirements are discussed elsewhere, e.g., in the DetNet WG. The terminology in this section should be better explained to readers dealing with networked systems with much harder latency requirements. And a reference should be added for these definitions in the context of video streaming.


Question: both were then selected as the default TCP congestion controllers in Linux, and both were deployed globally. <del> The point mentioned in tcp-behavior about TCP congestion controllers being implemented in operating system kernels is different with QUIC. Although QUIC can be implemented in operating system kernels, one of the design goals when this work was chartered was "QUIC is expected to support rapid, distributed development and testing of features," and to meet this expectation, many implementers have chosen to implement QUIC in user space, outside the operating system kernel, and to even distribute QUIC libraries with their own applications. It is worth noting that streaming operators using HTTP/3, carried over QUIC, can expect more frequent deployment of new congestion controller behavior than has been the case with HTTP/1 and HTTP/2, carried over TCP. </del> <ins> The point mentioned in reliable-behavior about TCP congestion controllers being implemented in operating system kernels is different with QUIC.  Although QUIC can be implemented in operating system kernels, one of the design goals when this work was chartered was "QUIC is expected to support rapid, distributed development and testing of features," and to meet this expectation, many implementers have chosen to implement QUIC in user space, outside the operating system kernel, and to even distribute QUIC libraries with their own applications.  It is worth noting that streaming operators using HTTP/3, carried over QUIC, can expect more frequent deployment of new congestion controller behavior than has been the case with HTTP/1 and HTTP/2, carried over TCP. </ins> It is worth considering that if TCP-based HTTP traffic and UDP-based HTTP/3 traffic are allowed to enter operator networks on roughly

Section 5.5.2 Head-of-Line Blocking If Head-of-Line Blocking is indeed a relevant operational problem, it would be useful to add a corresponding reference (e.g., with measurements). Section 5.5.3. Wide and Rapid Variation in Path Capacity The statement "As many end devices have moved to wireless connectivity for the final hop (Wi-Fi, 5G, or LTE), new problems in bandwidth detction have emerged from radio interference and signal strength effects." could be moved to earlier parts of the document. Quite a bit of new computers apparently only have Wifi connectivity and no Ethernet port, i.e., Wifi may just be their default. Also, wireless may not only be used on the last hop, for instance in meshed setups. This may make the problem even harder. Section 6. Evolution of Transport Protocols and Transport Protocol Behaviors I really wonder whether UDP vs. TCP vs. QUIC is actually the relevant distinction. What may actually matter are the transport services provided by the protocol stack (e.g., RFC 8095). I fully agree to a related comment in the INTDIR review. Section 6.1. UDP and Its Behavior UDP is also used for encrypted tunnels (OpenVPN, Wireguard, etc.). Does encrypted tunneling really have no operational impact on streaming apps other than circuit breakers? (I am thinking about 4K streaming over OpenVPN and the like.) Section 6.2. TCP and Its Behavior This text should IMHO be presented and be discussed in TCPM. Personally, I am not convinced that this document is a good place for discussing the long history of TCP congestion control. If the objective of the document is to provide a tutorial, IMHO it would be more useful to briefly explain the state-of-the-art in year 2022. Some further specific comments on TCP congestion control: It is surprising that RFC 5681 is not referenced.793bis has normative statements regarding congestion control, and most stacks are compatible to what is written in 793bis. Several operating systems use CUBIC by default and support standard Reno. Another general good reference for TCP standards is RFC 7414.Does ECN, DCTCP, etc. really not matter at all, for instance, if a data center hosts video playout servers?


Question: both were then selected as the default TCP congestion controllers in Linux, and both were deployed globally. <del> The point mentioned in tcp-behavior about TCP congestion controllers being implemented in operating system kernels is different with QUIC. Although QUIC can be implemented in operating system kernels, one of the design goals when this work was chartered was "QUIC is expected to support rapid, distributed development and testing of features," and to meet this expectation, many implementers have chosen to implement QUIC in user space, outside the operating system kernel, and to even distribute QUIC libraries with their own applications. It is worth noting that streaming operators using HTTP/3, carried over QUIC, can expect more frequent deployment of new congestion controller behavior than has been the case with HTTP/1 and HTTP/2, carried over TCP. </del> <ins> The point mentioned in reliable-behavior about TCP congestion controllers being implemented in operating system kernels is different with QUIC.  Although QUIC can be implemented in operating system kernels, one of the design goals when this work was chartered was "QUIC is expected to support rapid, distributed development and testing of features," and to meet this expectation, many implementers have chosen to implement QUIC in user space, outside the operating system kernel, and to even distribute QUIC libraries with their own applications.  It is worth noting that streaming operators using HTTP/3, carried over QUIC, can expect more frequent deployment of new congestion controller behavior than has been the case with HTTP/1 and HTTP/2, carried over TCP. </ins> It is worth considering that if TCP-based HTTP traffic and UDP-based HTTP/3 traffic are allowed to enter operator networks on roughly

Section 6.3. QUIC and Its Behavior As already noted, the discussion about head-of-line-blocking would really benefit from backing by a reference. Section 7. Streaming Encrypted Media As far as I know, streaming users sometimes use encrypted tunnels such as OpenVPN or WireGuard (or IPsec) to access video content. I may miss something, but it is unclear to me how that fits into the categories presented in Section


Question: "Upgrade". the response SHALL include a single "Upgrade" header with value <del> "masque-udp". </del> <ins> "connect-udp". </ins> the response SHALL NOT include any Transfer-Encoding or Content- Length header fields.

Should the upgrade token be "connect-udp" or "masque-udp" ? (issue based on by NAME
I vote for or something along those lines. "MASQUE" is good as a working group name, but I don't think it's helpful in the protocol to help people understand what the variant of CONNECT does.


Question: and header protection, as a connection error of type PROTOCOL_VIOLATION.  Discarding such a packet after only removing header protection can expose the endpoint to attacks; see <del> Section 9.3 of QUIC-TLS. </del> <ins> Section 9.5 of QUIC-TLS. </ins> The next bit (0x04) of byte 0 indicates the key phase, which allows a recipient of a packet to identify the packet protection

There are three places which refer to "Section 9.3 of QUIC-TLS". I think they should refer to "Section 9.5 of QUIC-TLS".
Thanks!


Question: constrain the types of information for which the trust anchor is authoritative."  The trust anchor may be a certificate or it may be a raw public key along with additional data if necessary such as its <del> public key algorithm and parameters. </del> <ins> public key algorithm and parameters.  In the context of this document, a trust anchor may also be a symmetric key, as in TCG-DICE- SIBDA or the symmetric mode described in I-D.tschofenig-rats-psa- token. </ins> Thus, trusting a Verifier might be expressed by having the Relying <del> Party store the Verifier's public key or certificate in its trust anchor store, or might be expressed by storing the public key or certificate of an entity (e.g., a Certificate Authority) that is in the Verifier's certificate path.  For example, the Relying Party can </del> <ins> Party store the Verifier's key or certificate in its trust anchor store, or might be expressed by storing the public key or certificate of an entity (e.g., a Certificate Authority) that is in the Verifier's certificate path.  For example, the Relying Party can </ins> verify that the Verifier is an expected one by out of band establishment of key material, combined with a protocol like TLS to communicate.  There is an assumption that between the establishment

Throughout the document the term "trust anchor" is meant in the to be a public key and associated (meta)data. This definition does not cover attestation schemes based on symmetric crypto, e.g., , and Arm PSA, and should be extended to also cover such cases.
Was there specific text that you believe needs to be changed?
yes, we identified at least two places: §7.1 and §12.4.
Reads great to me. Any other opinions?


Question: The output of the decryption is the server ID that the load balancer uses for routing. <del> 4.3.3. </del> <ins> 4.2.3. </ins> When generating a routable connection ID, the server writes arbitrary bits into its nonce octets, and its provided server ID into the

by popular demand in .
As discussed at IETF 108. Split from .
Thanks for filing this. I agree that this was the feedback, but I'll take it from the list to be sure.
Removing this seems fine to me.
Yes, do it.
Seems fine.
Do it.
Do it.
Nick Harper concurred on the list
Yes, that works. Minor comment.


Question: 5. Several types of ciphers have been defined for use with TLS and DTLS <del> and the MAC calculation for those ciphers differs slightly. </del> <ins> and the MAC calculations for those ciphers differ slightly. </ins> <del> This specification modifies the MAC calculation defined in RFC6347 and RFC7366 as well as the definition of the additional data used with AEAD ciphers provided in RFC6347 for records with content type </del> <ins> This specification modifies the MAC calculation as defined in RFC6347 and RFC7366, as well as the definition of the additional data used with AEAD ciphers provided in RFC6347, for records with content type </ins> tls12_cid.  The modified algorithm MUST NOT be applied to records that do not carry a CID, i.e., records with content type other than tls12_cid.

This is supposed to all be editorial stuff, and I split a couple changes out into separate commits in case they're not actually desired.


Question: 3.2. <del> This document focuses on QUIC version 1, and this section applies only to packets belonging to QUIC version 1 flows; for purposes of on-path observation, it assumes that these packets have been identified as such through the observation of a version number exchange as described above. </del> <ins> This document focuses on QUIC version 1, and this Connection Confirmation section applies only to packets belonging to QUIC version 1 flows; for purposes of on-path observation, it assumes that these packets have been identified as such through the observation of a version number exchange as described above. </ins> Connection establishment uses Initial and Handshake packets containing a TLS handshake, and Retry packets that do not contain

This goes to the end of "Server Name Indication" Some changes are attempts at clarifications, but I could have incorrectly clarified something, so feel free to reject changes.


Question: 7.1.2. <ins> When sending to a zero-length CID receiver, senders may receive acknowledgements that combine packet numbers received over multiple paths.  However, even if one packet number space is used on multiple path the sender MUST maintain separate congestion control state for each path.  Therefore, senders MUST be able to infer the sending path from the acknowledged packet numbers, for example by remembering which packet was sent on what path.  The senders MUST use that information to perform congestion control on the relevant paths, and to correctly estimate the transmission delays on each path.  (See ack-delay-and-zero-length-cid-considerations for specific considerations about using the ACK Delay field of ACK frames, and ecn-handling for issues on using ECN marks.) Loss detection as specified in QUIC-RECOVERY uses algorithms based on timers and on sequence numbers.  When packets are sent over multiple paths, loss detection must be adapted to allow for different RTTs on different paths.  When sending to zero-length CID receivers, packets sent on different paths may be received out of order.  Therefore senders cannot directly use the packet sequence numbers to compute the Packet Thresholds defined in Section 6.1.1 of QUIC-RECOVERY. Relying only on Time Thresholds produces correct results, but is somewhat suboptimal.  Some implementations have been getting good results by not just remembering the path over which a packet was sent, but also maintaining an order list of packets sent on each path.  That ordered list can then be used to compute acknowledgement gaps per path in Packet Threshold tests. 7.1.3. </ins> The ACK Delay field of the ACK frame is relative to the largest acknowledged packet number (see Section 13.2.5 of QUIC-TRANSPORT). When using paths with different transmission delays, the reported

This derives from the discussions on issue
The commit applies the changes suggested in the previous reviews. With those changes, I think we have a good basis for discussing a unified solution in the working group.
Thanks NAME for the review. I have applied the editorial changes. You are asking for something more regarding the "specific logic" required when supporting zero-length CID. There are in fact two pieces to that: logic at the receiver, i.e., the node that chose to receive packets with zero-length CID; and logic at the sender, i.e., the node that accepts to send data on multiple paths towards a node that uses zero-length CID. This is explained in details in the section "Using Zero-Length connection ID", so I guess what we need is a reference to that section.
Comment by NAME (on PR ): I think we expand this section a bit as we found getting the delay right was non-trivial. QUIC time-stamp would work for sure. But if one decides not to use QUIC timestamp, we probably want to explain what is needed to be done here.
I have submitted PR for this one.
Closing as got merged.
In section 3.1, we wrote When the multipath option is negotiated, clients that want to use an additional path MUST first initiate the Address Validation procedure with PATHCHALLENGE and PATHRESPONSE frames described in of ]. After receiving packets from the client on the new paths, the servers MAY in turn attempt to validate these paths using the same mechanisms. With multipath, we cannot simply write that the server MAY validate the new path. There is a risk of a malicious client that operates as follows: client creates path from its own address, A. Path is validate by server client starts long download from server client creates a second path to server using a spoofed address, B client starts address validation for B but does not care about the response from the server client stops acknowledging packets over the first path to force the server to move packets to the second one and then opportunistically acknowledges packets that should have been sent by the server over that second packet (SPNS would probably make such an attack simpler than MPNS) We probably need to start working on the security considerations section of the draft.
This is already covered in the QUIC threat model. The server is supposed to validate new paths by sending a "path challenge" on that path, then waiting for a challenge response.


Question: 7.1.2. <ins> When sending to a zero-length CID receiver, senders may receive acknowledgements that combine packet numbers received over multiple paths.  However, even if one packet number space is used on multiple path the sender MUST maintain separate congestion control state for each path.  Therefore, senders MUST be able to infer the sending path from the acknowledged packet numbers, for example by remembering which packet was sent on what path.  The senders MUST use that information to perform congestion control on the relevant paths, and to correctly estimate the transmission delays on each path.  (See ack-delay-and-zero-length-cid-considerations for specific considerations about using the ACK Delay field of ACK frames, and ecn-handling for issues on using ECN marks.) Loss detection as specified in QUIC-RECOVERY uses algorithms based on timers and on sequence numbers.  When packets are sent over multiple paths, loss detection must be adapted to allow for different RTTs on different paths.  When sending to zero-length CID receivers, packets sent on different paths may be received out of order.  Therefore senders cannot directly use the packet sequence numbers to compute the Packet Thresholds defined in Section 6.1.1 of QUIC-RECOVERY. Relying only on Time Thresholds produces correct results, but is somewhat suboptimal.  Some implementations have been getting good results by not just remembering the path over which a packet was sent, but also maintaining an order list of packets sent on each path.  That ordered list can then be used to compute acknowledgement gaps per path in Packet Threshold tests. 7.1.3. </ins> The ACK Delay field of the ACK frame is relative to the largest acknowledged packet number (see Section 13.2.5 of QUIC-TRANSPORT). When using paths with different transmission delays, the reported

If the client spoofs a path, it will never receive the challenge, and thus the server will never receive the response and will not validate the path. See section 8.2 of RFC 9000, path validation. Security section 21.1.3. Connection Migration states that "Path validation () establishes that a peer is both willing and able to receive packets sent on a particular path."
So yes, the current text should be "the servers MUST in turn attempt to validate these paths using the same mechanisms, as specified in {{ Section 8.2 of RFC9000 }}."
No, this should not be a MUST. It is true that the path MUST be validated before it can be used. However, just because the serve receives a new packet on a path, that doesn't automatically mean that the server has to start path validation. It could e.g. also decide to simply withdraw that packet.
Actually, this is also not right. This is what RFC9000 says (section 9): So I guess we should maybe not use normative language here but refer to section 9 in RFC9000 instead...?
Just submitted PR for this issue.
This draft initially originates from a merging effort of previous Multipath proposals. While many points were found to be common between them, there remains one design point that still requires consensus: the number of packet number spaces that a Multipath QUIC connection should support (i.e., one for the whole connection vs. one per path). The current draft enables experimentation with both variants, but in the final version we will certainly need to choose between one of the versions.
The main issues mentioned so far: Efficiency. One number space per path should be more efficient, because implementations can directly reuse the loss-recovery logic specified for QUIC ACK size. Single space leads to lots of out of order delivery, which causes ACK sizes to grow Simplicity of code. Single space can be implemented without adding mane new code paths to uni-path QUIC Shorter header. Single space works well with NULL length CID The picoquic implementation shows that "efficiency" and "ack size" issues of single space implementations can be mitigated.


Question: 7.1.2. <ins> When sending to a zero-length CID receiver, senders may receive acknowledgements that combine packet numbers received over multiple paths.  However, even if one packet number space is used on multiple path the sender MUST maintain separate congestion control state for each path.  Therefore, senders MUST be able to infer the sending path from the acknowledged packet numbers, for example by remembering which packet was sent on what path.  The senders MUST use that information to perform congestion control on the relevant paths, and to correctly estimate the transmission delays on each path.  (See ack-delay-and-zero-length-cid-considerations for specific considerations about using the ACK Delay field of ACK frames, and ecn-handling for issues on using ECN marks.) Loss detection as specified in QUIC-RECOVERY uses algorithms based on timers and on sequence numbers.  When packets are sent over multiple paths, loss detection must be adapted to allow for different RTTs on different paths.  When sending to zero-length CID receivers, packets sent on different paths may be received out of order.  Therefore senders cannot directly use the packet sequence numbers to compute the Packet Thresholds defined in Section 6.1.1 of QUIC-RECOVERY. Relying only on Time Thresholds produces correct results, but is somewhat suboptimal.  Some implementations have been getting good results by not just remembering the path over which a packet was sent, but also maintaining an order list of packets sent on each path.  That ordered list can then be used to compute acknowledgement gaps per path in Packet Threshold tests. 7.1.3. </ins> The ACK Delay field of the ACK frame is relative to the largest acknowledged packet number (see Section 13.2.5 of QUIC-TRANSPORT). When using paths with different transmission delays, the reported

However, that required significant improvements in the code: to obtain good loss efficiency, picoquic remembers not just the path on which a packet was sent, but also the order of the packet on this path, i.e. a "virtual sequence number". The loss detection logic then operates on that virtual sequence number. to contain ACK size, picoquic implements a prioritization logic to select the most important ranges in an ACK, avoid acking the same range more than 3 or 4 times, and keep knowledge of already acknowledged ranges so range coalescing works. I think these improvements are good in general, and I will keep them in the implementations whether we go for single space or not. The virtual sequence number is for example useful if the CID changes for reasons not related to path changes in multiple number space variants. It is also useful in unipath variants to avoid interference between sequence numbers used in probes and the RACK logic. The ACK size improvements do reduce the size of ACKs in presence of out of order delivery, e.g., if the network is doing some kind of internal load balancing. On the other hand, the improvements are somewhat complex, would need to be described in separate drafts, and pretty much contradicts the "simplicity of code" argument. So we are left with the "Null length CID" issue. I see for cases: Client CID Priority ----------------------- long Used by many implementations NULL Preferred configuration of many big deployments long Rarely used, server load balancing does not work NULL Only mentioned in some P2P deployments The point here is that it is somewhat hard to deploy a large server with NULL CID and use server load balancing. This configuration is mostly favored by planned P2P deployments.
The big debate is for the configuration with NULL CID on client, long CID on server. The packets from server to client do not carry a CID, and only the last bytes of the sequence number. The client will need some logic to infer the full sequence number before decrypting the packet. The client could maybe use the incoming 5 tuple as part of the logic, but it is not obvious. It is much simpler to assume a direct map from destination CID to number space. That means, if a peer uses a NULL CID, all packets sent to that peer are in the same number space.


Question: 7.1.2. <ins> When sending to a zero-length CID receiver, senders may receive acknowledgements that combine packet numbers received over multiple paths.  However, even if one packet number space is used on multiple path the sender MUST maintain separate congestion control state for each path.  Therefore, senders MUST be able to infer the sending path from the acknowledged packet numbers, for example by remembering which packet was sent on what path.  The senders MUST use that information to perform congestion control on the relevant paths, and to correctly estimate the transmission delays on each path.  (See ack-delay-and-zero-length-cid-considerations for specific considerations about using the ACK Delay field of ACK frames, and ecn-handling for issues on using ECN marks.) Loss detection as specified in QUIC-RECOVERY uses algorithms based on timers and on sequence numbers.  When packets are sent over multiple paths, loss detection must be adapted to allow for different RTTs on different paths.  When sending to zero-length CID receivers, packets sent on different paths may be received out of order.  Therefore senders cannot directly use the packet sequence numbers to compute the Packet Thresholds defined in Section 6.1.1 of QUIC-RECOVERY. Relying only on Time Thresholds produces correct results, but is somewhat suboptimal.  Some implementations have been getting good results by not just remembering the path over which a packet was sent, but also maintaining an order list of packets sent on each path.  That ordered list can then be used to compute acknowledgement gaps per path in Packet Threshold tests. 7.1.3. </ins> The ACK Delay field of the ACK frame is relative to the largest acknowledged packet number (see Section 13.2.5 of QUIC-TRANSPORT). When using paths with different transmission delays, the reported

Revised table: Client CID What -- -- long Multiple number space NULL Multiple number spaces on client side (one per CID), single space on server side long Multiple number spaces on server side (one per CID), single space on client side NULL single number space on each side If a node advertises both NULL CID and multipath support, they SHOULD have logic to contain the size of ACK. If a node engages in multipath with a NULL CID peer, they SHOULD have special logic to make loss recovery work well.
I think the above points to a possible "unified solution": if multipath negotiated, tie number spaces to destination CID, use default (N=0) if NULL CID. use multipath ack; in multipath ACK, identify number space by sequence number of DCID in received packets. Default that number to zero if received with NULL CID. in ABANDON path, identify path either by DCID of received packets, SCID of sent packet, or "this path" (sending path) if CID is NULL.
I like the proposal of the "unified solution". I think the elegance lies in the fact that it allows us to automatically cover all four cases listed above. The previous dilemma for me was that on one hand we have some use cases where we need to support more than two paths and separate PN makes the job easier, but on the other hand, I think we should not ignore the NULL CID use cases as it is also important. Now, with this proposal, a big part of the problem is solved. The rest of challenge is to make sure single PN remains efficient in terms of ACK and loss recovery. On that part, we plan to do an A/B test and would love to share the results when we get them. There is one more problem as pointed in issue , when we want to take hardware offloads into account. In such a case, we may still need single PN for long server CID. However, if hardware supports nonce modification, this problem can be addressed with the proposed "unified solution".
If the APi does not support 96 bit sequence numbers, it should always be possible to create an encryption context per number space, using Key=current key and ID = current-ID + CID sequence number. Of course, that forces creation of multiple context, and that makes key rotation a bit harder to manage. But still, that should be possible.


Question: 7.1.2. <ins> When sending to a zero-length CID receiver, senders may receive acknowledgements that combine packet numbers received over multiple paths.  However, even if one packet number space is used on multiple path the sender MUST maintain separate congestion control state for each path.  Therefore, senders MUST be able to infer the sending path from the acknowledged packet numbers, for example by remembering which packet was sent on what path.  The senders MUST use that information to perform congestion control on the relevant paths, and to correctly estimate the transmission delays on each path.  (See ack-delay-and-zero-length-cid-considerations for specific considerations about using the ACK Delay field of ACK frames, and ecn-handling for issues on using ECN marks.) Loss detection as specified in QUIC-RECOVERY uses algorithms based on timers and on sequence numbers.  When packets are sent over multiple paths, loss detection must be adapted to allow for different RTTs on different paths.  When sending to zero-length CID receivers, packets sent on different paths may be received out of order.  Therefore senders cannot directly use the packet sequence numbers to compute the Packet Thresholds defined in Section 6.1.1 of QUIC-RECOVERY. Relying only on Time Thresholds produces correct results, but is somewhat suboptimal.  Some implementations have been getting good results by not just remembering the path over which a packet was sent, but also maintaining an order list of packets sent on each path.  That ordered list can then be used to compute acknowledgement gaps per path in Packet Threshold tests. 7.1.3. </ins> The ACK Delay field of the ACK frame is relative to the largest acknowledged packet number (see Section 13.2.5 of QUIC-TRANSPORT). When using paths with different transmission delays, the reported

Thanks for the summary NAME I think one point is missing in your list which is related to issue . Use of a single packet number space might not support ECN. Regarding the unified solution: I think what you actually say is that we would specify both solutions and everybody would need to implement both logics. At least regarding the "simplicity of code" argument, that would be the worst choice. If we can make the multiple packet number spaces solution work with one-sided CIDs, I'm tending toward such an approach. Use of multiple packet number spaces avoids ambiguity/needed "smartness" in ACK handling and packet scheduling which, as you say above, can make the implementation more complex and, moreover, wrong decisions may have large impact on efficient (both local processing and on-the-wire). I don't think we want to leave these things to each implementation individually.
The summary Christian made above about design comparison sounds indeed quite accurate. Besides ECN, my other concern about single packet number is that it require cleverness from the receiver side if you want to be performant in some scenarios. At the sender-side, you need to consider a path-relative packet number threshold instead of an absolute one to avoid spurious losses. Just a point I think we did not mentioned yet is that there can be some interactions between Multipath out-of-order number delivery and incoming packet number duplicate detection. This requires maintaining some state at the receiver side, as described by URL With single packet number space, the receiver should take extra care when updating the "minimum packet number below which all packets are immediately dropped". Otherwise, in presence of paths with very different latencies, the receiver might end up discarding packets from a (slower) path. I'm also preferring the multiple packet number spaces solution for the above reasons. I'm not against thinking for a "unified" solution (the proposal sounds interesting), but I wonder how much complexity this would add compared to requiring end hosts to use one-byte CIDs.
I think the issue is not really so much "single vs multiple number space" as "support for multipath and NULL CID". As noted by Mirja, there is an implementation cost there. My take is: If a node uses NULL CID and proposes support of multipath, then that node MUST implement code to deal with size of acknowledgements.


Question: 7.1.2. <ins> When sending to a zero-length CID receiver, senders may receive acknowledgements that combine packet numbers received over multiple paths.  However, even if one packet number space is used on multiple path the sender MUST maintain separate congestion control state for each path.  Therefore, senders MUST be able to infer the sending path from the acknowledged packet numbers, for example by remembering which packet was sent on what path.  The senders MUST use that information to perform congestion control on the relevant paths, and to correctly estimate the transmission delays on each path.  (See ack-delay-and-zero-length-cid-considerations for specific considerations about using the ACK Delay field of ACK frames, and ecn-handling for issues on using ECN marks.) Loss detection as specified in QUIC-RECOVERY uses algorithms based on timers and on sequence numbers.  When packets are sent over multiple paths, loss detection must be adapted to allow for different RTTs on different paths.  When sending to zero-length CID receivers, packets sent on different paths may be received out of order.  Therefore senders cannot directly use the packet sequence numbers to compute the Packet Thresholds defined in Section 6.1.1 of QUIC-RECOVERY. Relying only on Time Thresholds produces correct results, but is somewhat suboptimal.  Some implementations have been getting good results by not just remembering the path over which a packet was sent, but also maintaining an order list of packets sent on each path.  That ordered list can then be used to compute acknowledgement gaps per path in Packet Threshold tests. 7.1.3. </ins> The ACK Delay field of the ACK frame is relative to the largest acknowledged packet number (see Section 13.2.5 of QUIC-TRANSPORT). When using paths with different transmission delays, the reported

If a node sees a peer using NULL CID and supporting multipath, then that node MUST either use only one path at a time or implement code to deal with impact on loss detection due to out of order arrivals, and impact on congestion control including ambiguity of ECN signals. Then add sections on what it means to deal with the side of acknowledgements, out of order arrivals, and congestion control. I think this approach ends up with the correct compromises: It keeps the main case simple. Nodes that rely on multipath just use long CID and one number space per CID. Nodes that use long CID never have to implement the ACK length minimization algorithms. Nodes that see a peer using NULL CID have a variety of implementation choices, e.g., sending on just one path at a time, sending on mostly one path at a time in "make or break" transitions, or implementing sophisticated algorithms. If we do that, we can get rid of the single vs multiple space discussion, and end up with a single solution addressing all use cases.
Looking at all the discussions here and in other issues such as ECN, I think that we should try to write two different versions of section 7: one covering all the aspects of single packet number space (RTT estimation, retransmissions, ECN, handling of CIDs, ...) one covering all the aspects of multiple packet number space (RTT estimation, retransmissions, ECN, handling of CIDs, ...) There would be some overlap between these two sections and also some differences that would become clear as we specify them. At the end of this writing, we'll know whether it is possible to support/unify both or we need to recommend a single one. The other parts of the document are almost independent of that and can evolve in parallel with these two sections. However, I don't think that such a change would be possible by Monday
I don't think we should rush changes before we have agreed on the final vision.
It might be helpful to have these options as PRs (without merging) them, so people can understand all details of each approach.
I agree with NAME that supporting multi-path with null CIDs is a more fundamental issue than the efficiency comparison between single PN and separate PN, as it would ultimately impact the application scope of multipath QUIC. But indeed, we might want to implement proposed solution first and then decide if we want to adopt such a unified approach.


Question: 7.1.2. <ins> When sending to a zero-length CID receiver, senders may receive acknowledgements that combine packet numbers received over multiple paths.  However, even if one packet number space is used on multiple path the sender MUST maintain separate congestion control state for each path.  Therefore, senders MUST be able to infer the sending path from the acknowledged packet numbers, for example by remembering which packet was sent on what path.  The senders MUST use that information to perform congestion control on the relevant paths, and to correctly estimate the transmission delays on each path.  (See ack-delay-and-zero-length-cid-considerations for specific considerations about using the ACK Delay field of ACK frames, and ecn-handling for issues on using ECN marks.) Loss detection as specified in QUIC-RECOVERY uses algorithms based on timers and on sequence numbers.  When packets are sent over multiple paths, loss detection must be adapted to allow for different RTTs on different paths.  When sending to zero-length CID receivers, packets sent on different paths may be received out of order.  Therefore senders cannot directly use the packet sequence numbers to compute the Packet Thresholds defined in Section 6.1.1 of QUIC-RECOVERY. Relying only on Time Thresholds produces correct results, but is somewhat suboptimal.  Some implementations have been getting good results by not just remembering the path over which a packet was sent, but also maintaining an order list of packets sent on each path.  That ordered list can then be used to compute acknowledgement gaps per path in Packet Threshold tests. 7.1.3. </ins> The ACK Delay field of the ACK frame is relative to the largest acknowledged packet number (see Section 13.2.5 of QUIC-TRANSPORT). When using paths with different transmission delays, the reported

Since NAME prodded me, we now have a PR for the "unified" proposal.
I totally agree with Christian that the issue is about "support for multipath and NULL CID", and the solution that Christian suggested looks really great! It both takes advantage of multiple spaces, and support NULL CID users without affect the efficiency of ACK arrangements. Besides, the solution is more convenient for implementations, because If both endpoints uses non-zero length cids, endpoints only need to support multiple spaces, and if one of the endpoints use NULL CID, it could use single pn space in one direction and could support NULL CID and multipath at the same time.
Very high level summary of IETF-113 discussion seems that there is interest and likely support for the unified solution (review minutes for further details).


Question: A URL for the certificate that has been issued in response to this application. <del> [[ Open issue: There are two possible behaviors for the CA here. Either (a) the CA automatically issues once all the requirements are fulfilled, or (b) the CA waits for confirmation from the client that it should issue.  If we allow both, we will need a signal in the application object of whether confirmation is required.  I would prefer that auto-issue be the default, which would imply a syntax like "confirm": true ]] [[ Open issue: Should this syntax allow multiple certificates?  That would support reissuance / renewal in a straightforward way, especially if the CSR / notBefore / notAfter could be updated. ]] </del> The elements of the "requirements" array are immutable once set, except for their "status" fields.  If any other part of the object changes after the object is created, the client MUST consider the

Based on the acme mailing list discussion[0] on "proactive" vs "on-finalization" issuance it seems there is more support for the proactive approach. Speaking on behalf of Let's Encrypt and the Boulder developers we're willing to compromise and support proactive issuance as the sole issuance method in order to simplify the protocol & implementations. This PR changes the language around certificate issuance to reflect that the server MUST issue the certificate proactively once all the required challenges for an application have been fulfilled. The open issue corresponding to making this decision is removed now that there is one supported option. In an effort to close out open questions around applications this commit also removes the open issue around multiple certificates per application. If there is a demand for automating repeat issuance there should be a new thread started with a concrete proposal. 0: URL
NAME apologies! I missed your comments until today. Both are resolved in URL Thank you for the feedback.
Oh! They were fresh and I misread the dates. Not such a bad turn around after all :-)
NAME Fantastic, thanks. Merging. Hi folks, I wanted to revisit a discussion on the server proactively issuing certificates. Section 4, "Protocol Overview"[0] currently has a paragraph that reads: the the application be to the There is also an "Open Issue" remark related to proactive issuance in Section [1]. I think the specification should decide whether proactive issuance or on-finalization issuance should be used instead of allowing both with no indication to the client which will happen. It's the preference of Let's Encrypt that the specification only support on-finalization issuance. This is cheaper to implement and seems to be the path of least surprise. It also seems to better support large volume issuance when the client may want explicit control over when the certificates for multiple applications are issued. In the earlier "Re: [Acme] Preconditions" thread[2] Andrew Ayer seems to agree that there should be only one issuance method to simplify client behaviours, though he favours proactive issuance instead of on-finalization issuance. While it saves a round-trip message I'm not sure that this alone is convincing enough to choose proactive issuance as the one issuance method. What are the thoughts of other list members? Daniel/cpu [0] URL [1] URL [2] URL


Question: 7.3.4. <del> This method is indicated by "jws" in the "proof" field.  A JWS RFC7515 object is created as follows: </del> <ins> This method is indicated by the method value "jws".  This method defines no additional parameters.  A JWS RFC7515 object is created as follows: </ins> To protect the request, the JWS header contains the following claims.

Expands the key parameter to allow it to be an object or a string, to facilitate methods with multiple parameters such as HTTPSig.
To edit notification comments on pull requests, go to your .
Some key proofing methods have additional options that could be signaled in the GNAP protocol structure. Notable, HTTP Message Signatures has the ability to use different HTTP Signing Algorithms and different HTTP Digest Algorithms. The field could be changed to an object to accomodate this kind of use, allowing each proofing method to define its own parameters: Each method can also define "Default" values for missing parameters, allowing this to collapse in the simple case back to a string as it is today: These string values would have a deterministic expansion defined in the core protocol.
Note that the httpsig document itself wavers between and and does not require either of them. Though maybe this is OK if the current document makes mandatory for the appropriate cases.
There are some updates pending in the Digest draft -- once that's out, we'll reference using as that's the most appropriate for our use case, and examples will be updated.


Question: An endpoint that receives a NEW_CONNECTION_ID frame with a sequence number smaller than the Retire Prior To field of a previously <del> received NEW_CONNECTION_ID frame MUST immediately send a corresponding RETIRE_CONNECTION_ID frame that retires the newly received connection ID. </del> <ins> received NEW_CONNECTION_ID frame MUST send a corresponding RETIRE_CONNECTION_ID frame that retires the newly received connection ID, unless it has already done so for that sequence number. </ins> 19.16.

If you drop the first paragraph, this is just an editorial fix as far as I'm concerned. That is, not sending a frame that was previously sent is not a change. And - assuming that you dump it - "immediately" has no defined meaning anyway.
NAME I'm happy to drop the first paragraph, and I'm glad to hear that it's editorial. Two people on our team took the existing text to mean that we had to send RCID after receiving NCID even though we'd previously retired that sequence number. Update coming soon.
NAME Feel free to change to "editorial"
This is a small point, but it's pointlessly creating pain in our implementation and possibly some others. In Sec 19.15 (NEWCONNECTIONID frame): IMO this is poorly formulated. If the receiver has already sent an RCID frame for the sequence number and that RCID has been acked, it may have thrown away state for that sequence number and shouldn't have to resend a frame the peer has received. In particular, a buggy or malicious peer might send a very old sequence number, or the NCID receiver might have preemptively retired a sequence number it hadn't seen when it got the retire-prior-to field. Simply appending 'if has not already done so' to the text above would do the trick I think. I'm happy to file a PR unless most people think this is a terrible idea.
As a related point, it would be useful to say that an NCID receiver SHOULD NOT immediately retire old CIDs solely as the result of the NCID frame, except when instructed by Retire-Prior-to. This can lead to infinite loops if the peer tries to keep a specific number of CIDs available.
I think this would be a nice clarification. I think we already prohibit such behavior through the use of activeconnectionidlimit TP. Section 5.1.1 states: endpoints store received connection IDs for future use and advertise the number of connection IDs they are willing to store with the activeconnectionidlimit transport parameter. To paraphrase, by using the TP, an endpoint willing to retain N active connection IDs prohibits the peer from sending more than N.
I was probably unclear. For a while, our implementation was doing something dumb: each time it got a new CID, it started using it and retired all previous ones regardless of Retire Prior To.


Question: An endpoint that receives a NEW_CONNECTION_ID frame with a sequence number smaller than the Retire Prior To field of a previously <del> received NEW_CONNECTION_ID frame MUST immediately send a corresponding RETIRE_CONNECTION_ID frame that retires the newly received connection ID. </del> <ins> received NEW_CONNECTION_ID frame MUST send a corresponding RETIRE_CONNECTION_ID frame that retires the newly received connection ID, unless it has already done so for that sequence number. </ins> 19.16.

This created infinite loops where the client was trying to make sure that we always had two CIDs. We should probably warn against that. Please see if the text in the PR is clear enough.
Taking a look at the PR, I'm finding the proposed text to be a bit unclear, too. Based on the discussion on the list, this seems to be a misreading of the text itself. From the list: I don't believe that this is actually what the text says. The text says: This to me reads as "If you said everything below CID 10 is done, and then you send me CID 8, I must immediately send a RCID frame for 8 since I can't use it". I don't believe that there is any CID-specific state required at all for this. You do need to store the current highest value that you've ever seen for RPT, which is a single integer, I'll call it . Beyond that, when you get a NCID frame, you check the sequence number. If it's less than , you should immediately enqueue (which I think might be a reasonable wording change to make, since immediately seems to have caused concern when the intent was that you put it on the tracks leaving the station, not that you force the train out the door before it's allowed) a RCID frame for that sequence number. Note that a RCID frame contains a single value, the sequence number of the connection ID being retired, which incidentally is contained by the NCID frame you're responding to. We can argue as to whether or not you should bother to send RCID again when the same frame has been acked, but (a) storing that is actually more state and (b) we're working pretty hard to avoid tracking ACKs of packets. I might be missing something here -- can you help me understand the concern about storing state in order to meet the requirements of this text?
Yes, I concede that the original email was garbled. I read the original text the same way you do. The issue is that if I decide to retire immediately without actually having the sequence number, that should be sufficient. Making me send it again after the NCID is gratuitous, and in at least one implementation creates state solely to track this corner case.
Ah cool, that's excellent then!


Question: An endpoint that receives a NEW_CONNECTION_ID frame with a sequence number smaller than the Retire Prior To field of a previously <del> received NEW_CONNECTION_ID frame MUST immediately send a corresponding RETIRE_CONNECTION_ID frame that retires the newly received connection ID. </del> <ins> received NEW_CONNECTION_ID frame MUST send a corresponding RETIRE_CONNECTION_ID frame that retires the newly received connection ID, unless it has already done so for that sequence number. </ins> 19.16.

:) What's the state that gets created to track that case? If you retired them all upon getting RPT without checking to see if you had them yet, don't you still have to keep track of the RPT value or which ones you've already retired? I'm probably missing some other piece of state in this case...
I think what an endpoint is required to track are: active connection IDs sequence number of connection IDs that are being retired (but are yet to be acknowledged) When receiving a NCID frame with RPT, an endpoint checks if there are any active CIDs below the RPT, and retires them. I do not think an endpoint has to track RPT, though admittedly, I haven't implement them (yet).
NAME what you suggest would certainly work. However, a malicious peer could send an infinite number of NCIDs as long as it kept advancing rpt and didn't ack RCIDs, spiraling the state upwards. To avoid this, we keep a window of unacked but retired sequence numbers and construct RCID from that. That's why having an NCID come in well below the window results in additional state for us.
NAME Exactly. We have an issue for that problem: . Agreeing on what to do to resolve the unbounded state problem might help resolving this issue too.
Taking this as editorial based on the proposal (and promised tweaks).
Looks fine to me, though I do think it's better with some kind of language to send it sooner rather than later.


Question: MUST be able to dereference or process the key information in order to be able to sign the request. <ins> OPTIONAL.  A set of flags that represent attributes or behaviors of the access token issued by the AS. The values of the "flags" field defined by this specification are as follows: This flag indicates whether the token is bound to the client instance's key.  If the "bearer" flag is present, the access token is a bearer token, and the "key" field in this response MUST be omitted.  If the "bearer" flag is omitted and the "key" field in this response is omitted, the token is bound the request-client in its request for access.  If the "bearer" flag is omitted, and the "key" field is present, the token is bound to the key and proofing mechanism indicated in the "key" field. </ins> OPTIONAL.  Flag indicating a hint of AS behavior on token <del> rotation.  If this flag is set to the value "true", then the client instance can expect a previously-issued access token to continue to work after it has been rotate-access-token or the underlying grant request has been continue-modify, resulting in the issuance of new access tokens.  If this flag is set to the boolean value "false" or is omitted, the client instance can </del> <ins> rotation.  If this flag is present, then the client instance can expect a previously-issued access token to continue to work after it has been rotate-access-token or the underlying grant request has been continue-modify, resulting in the issuance of new access tokens.  If this flag is omitted, the client instance can </ins> anticipate a given access token will stop working after token rotation or grant request modification.  Note that a token flagged as "durable" can still expire or be revoked through any normal

URL match the flags array in the token request. While this is technically a breaking change, I think we should consider this editorial as this should have been changed when we made the original change to use a flags array in the request in .
:heavycheckmark: Deploy Preview for gnap-core-protocol-editors-draft ready! Built :hammer: Explore the source changes: 8c793bb446d82f053536358106485568fc457842 :mag: Inspect the deploy log: :sunglasses: Browse the preview:
You know, I had that thought, and I checked the request section and it doesn't have quotes. I'm going to add the quotes to both parts. This ended up with some other language changing, not just the examples, so let me know what you think.


Question: 8. This document makes multiple registrations in the registries defined <del> by HTTP3.  The allocations created by this document are all assigned permanent status and list a change controller of the IETF and a contact of the HTTP working group (ietf-http-wg@w3.org). </del> <ins> by RFC9114.  The allocations created by this document are all assigned permanent status and list a change controller of the IETF and a contact of the HTTP working group (ietf-http-wg@w3.org). </ins> 8.1. This document specifies two settings.  The entries in the following table are registered in the "HTTP/3 Settings" registry established in <del> HTTP3. </del> <ins> RFC9114. </ins> For formatting reasons, the setting names here are abbreviated by removing the 'SETTINGS_' prefix.

These track corrections I've asked the RFC Editor to make directly in their copy prior to publication. It appears that some http-core sections moved since the last time we did a full sweep of our references.


Question: address on multiple different networks, a Designated Resolver that has been discovered on one network SHOULD NOT be reused on any of the other networks without repeating the discovery process for each <del> network. However, if a given Unencrypted DNS Resolver designates a Designated Resolver that does not use a private or local IP address and can be verified using the mechanism described in verified, it MAY be used on different network connections so long as the subsequent connections over other networks can also be successfully verified using the mechanism described in verified.  This is a tradeoff between performance (by having no delay in establishing an encrypted DNS connection on the new network) and functionality (if the Unencrypted DNS Resolver intends to designate different Designated Resolvers based on the network from which clients connect). </del> <ins> network, since the same IP address may be used for different servers on the different networks. </ins> 4.2.

DISCUSS: CC NAME See my discuss on draft-ietf-add-ddr-11 for my generic ADD DNR/DDR concerns Resolver without some sort of validation Why not? What is the alternative? Using unencrypted DNS to the party that told you how and where to contact these (unvalidated) Designated Resolvers. Resolver that does not use a private or local IP address and can be verified using the mechanism described in Section 4.2, it MAY be used on different network connections so long as the subsequent connections over other networks can also be successfully verified using the mechanism described in Section 4.2. This seems to go against a lot of advise in the documents that networks must be treated independently. Also, the network wants you to use their designated resolver, so to say it is okay to use a totally different Designated Resolvers seems to violate the whole DNR/DDR architecture. This will also cause failure if there is split-DNS or internal-only data. Also, using "public IP" is not a good trustworthy method to prove that these IPs are truly the same Designated Resolver used by both networks. I can easily use an internal only zone with . IN A 8.8.8.8 and get a valid ACME'd certificate with SAN=. The user connecting to another network might now be switching from my private DNS on my stolen 8.8.8.8 IP to the real google DNS. address of the designating Unencrypted Resolver in a subjectAltName extension. How feasible is it to get a certificate with SAN=ip from one of the generally accepted root store CA's? Can you give me one example where I can get a certificate for with SAN=193.110.157.123 ? I do not think this is currently possible or easy. If I am right, that means all of Section 4.2 is wishful thinking and not realistic to get rolled out. (I know we can see the cert for 1.1.1.1, so it is possible, but I know of no ACME supported CA that issues these) discovered Designated Resolver. This creates a strange policy when compared to DNR where if you get a DHCP or RA for the Designated Resolver, which is also not validatable, that you do end up using it?