(sorry that it took me so long) This uses some text that is also in the interface draft.
This I would like us to discuss. Well I know we have discussed this before. As I am reading the Interface document after a long while and having read it along with the architecture document, I kind of strongly feel that the architecture document lack of description on framer and the states. These are mentioned and pictured in the architecture document but haven't been clear there. Hence, I kind of feel that we need to move this two sections to architecture document. Please discuss so that I can understand the reasoning of not doing so.
Regarding section 9.1.2, the framer description: I think it's good to be clear and complete in the API document, but I agree that framers should be appropriately described in the architecture document. I have the impression that the text in the -arch document on this matter may indeed be too short, while the text in the -interface document may be too long (although a little bit of repetition surely won't hurt here, it's good for this document to be understandable and clear on its own). Maybe some of it could be moved to -arch, or repeated there? Regarding section 11, Connection states: to me, this is fine as it is. Section 4.1 / figure 4 in the architecture document make state transitions pretty clear - and section 11 / figure 2 are just a more fine-grain look at these states as a way to explain exactly which Events will occur when. This seems needed in the API document, where all other Events and Actions are defined, and I would think that this is at a too detailed / fine-grain level for the architecture document.
NAME after giving it some more thoughts, I think your suggested approach should be fine , meaning we put more description of framer in the architecture document and leave the connection states to the Interface document.
NAME did you want to take a stab at this?
Looks great!


All references to "metadata" are now to "report_metadata". References to "CollectReq" are now "CollectionReq". References to "CollectResp" are now "Collection".
The current version of the draft renames field "metadata" to "report_metadata" in the Report structure, but does not do the same renaming in the ReportShare and InputShareAad structures. I think this naming should be consistent, though I don't have a preference between the alternatives.
Thanks for pointing this out! Can you send prepare a PR?
Fixed in
Thanks a bunch NAME


URL , can we be more specific here about the control signal we are talking about is QUIC protocol control signal not really other kind of control signal that the network might have? also here it is compared with TCP, should it also mention TCP with TLS?
I added the term "transport-layer" in PR . Does that help. I don't think TLS needs to be mentioned here.


Makes two minor fixes in the GOAWAY text, both editorial: Correctly references the MAXSTREAMS frame instead of the MAXSTREAM_ID frame Notes that servers need not (and cannot) send a GOAWAY if the client has used up all the possible stream IDs; the client simply won't be making any more requests.
This is a whatever...


Whether or not the user visits the User Portal is optional: the user could choose not to, or the Captive Portal may not provide one. Clarify that the case presented in the component diagram is the one where the User Portal is present, and where the user chooses to visit it.


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).


Update the aggregate request text to reflect recent protocol changes. Relax the requirement that all sub-requests use the same key config. Do URL, which was previously merged into the wrong branch.
NAME NAME please have a look when you can.
Per , the first step in the upload protocol is a POST to the leader server which returns information about helpers. In some yet to be specified cases, the response could include a challenge to be incorporated into reports. However I suspect that in most cases, the response will be static and so an idempotent, cacheable GET would be a better fit, especially since it would save clients a roundtrip to the helper on the hot path of submitting reports, and would make it possible for helpers to implement uploadstart by putting some static content in a CDN. HTTP GET requests don't have bodies, so we would have to figure out how to encode all the data in the current into the URI, which could be done as either path fragments in the URI (i.e., ) or as query parameters (i.e., ). We would of course need to make sure that don't preclude proof systems like the one alleged to exist in section 5.2 of "BBCp19".
Also, because the current protocol uses a POST for uploadstart, the implication is that for every report they submit, clients need to hit and then . If we make idempotent and cacheable, then that request can be skipped in the majority of cases. I suppose the significance of this depends on how we expect clients to use PDA: are they going to be continuously streaming hundreds or thousands of reports into the leader as events of interest occur (in which case I think eliminating requests is interesting) or are they expected to accumulate several reports locally before submitting them all in one or a few requests?
I agree this would be a good change, if we can swing it. It's notable that Prio v2 and HH don't require a random challenge from the leader. But as discussed, this is useful for other proof systems one might want to implement for Prio. For example, see the data type implemented here: URL See below for an explanation. There might be other ways to implement the challenge. One possibility is to derive the challenge from the TLS key schedule (or from whatever state the client and leader share for the secure channel).


NAME and NAME have both pointed out that adding this dependency on the underlying transport is problematic. Another possibility might be to use some external source of randomness that the leader trusts. comes to mind, though it is somewhat problematic because clients would effectively use the same randomness for some period of time. The security model of BBCp19 would need to be extended to account for this. (I believe this could be done.) Some other solution I'm missing? _ This data type is used to compute the mean and variance of each integer in a sequence of integers. To do so, the client encodes each integer of its input vector as a pair , where is the representation of as a bit vector and is equal to . To prove validity of its input, the proof needs to do two things: verify that (a) is indeed a bit vector, and (b) the integer encoded by is the square root of . In order to check these things efficiently, the proof system uses a random challenge generated by the leader. At a very high level, the client wants to prove that the following boolean conjunction holds: is 1 or 0 AND is 1 or 0 AND ... AND encodes the square root of . In Prio, we need to represent this conjunction as an arithmetic circuit, which the random challenge helps us do. In a bit more detail now: Let's rewrite this expression as w[0] AND w[1] AND ... AND w[s]. As an arithmetic circuit, this expression is actually , where if and only if w[i] is true. If the input is valid, then the expression should evaluate to . But because we're talking about field elements, a malicious client may try to play games like setting and so that the sum is still , but the statement is false. To detect this, we actually compute the following expression: , where is a randomly chosen field element. If the statement is true, then the expression evaluates to . If the statement is false, then with high probability, the expression will evaluate to something other than . (This idea comes from Theorem 5.3)
Thank you for the detailed explanalation NAME Having thought about it more, I suspect an HTTP GET wouldn't be the right way to support proof systems that need a challenge.


Assuming that a unique challenge is needed for every report[^1], then intuitively the leader would have to maintain a mapping of reports to issued challenges so that the leader and helper(s) can later use the challenge value when evaluating the client's proof. But now that the leader has to maintain state per-report, I think the upload protocol is missing a notion of a report identifier. The contains a , but IIUC the will be the same across many reports[^2] (e.g., if a browser is sending daily reports on how often users click a button, they use the same every time they submit). So needs to include a report ID, which must be echoed back to the leader in so that the leader can look up the challenge for the report. [^1] Is this true? Or would it suffice for each to use the same challenge across multiple reports? [^2] I notice that the design doc lacks a strong definition of a report and how it relates to tasks, inputs, measurements: because GET should be "safe" in the sense of not changing any server state, and it seems like the server would have to maintain a mapping of reports to issued challenges so that the leader and helper can later use the challenge value when evaluating the client's proof.
Continuing on the assumption that causes a state change on the leader, POST is then the appropriate HTTP method to use. , though it's a little unusual. There may be some big drawback to cacheable POST responses, but I think that might let us support proof systems that require live challenges while also eliminating the majority of requests when the proof system is such that the will change very rarely.
The requirement for the leader to keep state across upload start and upload finish may be avoidable. Suppose the leader has a long-lived PRF key K. It would could choose a random nonce N, compute R = PRF(K, N) as the challenge, and hand (N, R) to the client in its upload start response. The client would then use R to generate the proof and send N to the leader in its upload finish request. The leader could then re-derive R. NAME and I kicked around the idea of having the client generate a report ID. I think this may end up being useful, but we weren't sure if it was better to have the leader choose it or the client.


To conform to the security model of BBCp19, each report would need its own challenge. It may be possible to relax this, but this would be risky.
I like this a lot! I'm a big fan of deterministic derivation schemes like this -- besides reintroducing the possibility of an idempotent GET, eliminating storage requirements for challenges makes it much easier to scale up leaders. If the report IDs are big enough (UUIDs?) we could even use them as . I would say the leader, because if you let the client do it, then the leader would have to check for things like collisions with existing report IDs or other malicious ID choices. If the leader chooses it, then all it has to do is generate a few bytes of randomness. I agree.
NAME we'd appreciate your feedback on this issue because it involves security considerations for ZKP systems on secret-shared data [1]. I'll quickly sum up the problem so that you don't need to worry about the conversation above. The problem at hand regards systems like [1, Theorem 5.3] that require interaction between the prover and verifier. Specifically, we're considering a special case of Theorem 5.3 in which the verifier sends the prover a random "challenge" that is used to generate and verify a (non-interactive) FLPCP (call it ): We refer to the prover's first and second messages as "upload start" and "upload finish" respectively. Each message corresponds to an HTTP request made by a web client to a web server. Ideally, the verifier would be able to handle these requests statelessly, i.e., without having to store . Consider the following change. Suppose the verifier has a long-term PRF key . In response to an upload start request, it chooses a unique "upload id" --- maybe this is a 16-byte integer chosen at random --- and computes and sends to the prover. In the upload finish request, the prover sends so that the verifier can re-derive instead of needing to remember it: The (potential) problem with this variant is that a malicious client is able to replay a challenge as many times as it wants.


This behavior isn't accounted for in Definition 3.9, so when you try to "compile" this system into a ZKP on secret-shared data as described in Section 6.2 and consider its security with respect to Definition 6.4 (Setting I), you can no longer appeal to Theorem 6.6 to reason about its security. Our question is therefore: What impact do you expect this change to have on the soundness of the system? Can you think of an attack that exploits the fact that challenges can be replayed? My expectation is that the problem is merely theoretical, i.e., we ought to be able to close the gap with an appropriate refinement of Definition of 3.9 and reproving Theorem 5.3. [1] URL
Thanks for looping me in. In the discussion below, I am assuming that the client sends its data vector (called "x" in the paper [1]) at the same time as it sends its proof to the verifier. Even if the client sends its data vector in the first message, it seems that the client can reuse an (R,N) pair from upload request 1 to later submit upload request 2, in which case the client sees (R, N) before it chooses its data vector and proof. So I think we can assume that the client's data vector and proof can depend on the verifier's random value R. (I'll call this value "r" to match the paper.) For soundness: the client/prover must commit to its data vector before it learns the verifier's random value r. If the prover can choose its data value and proof in a way that depends on the verifier's randomness r, the soundness guarantee no longer holds. There is also an efficient attack. So I suspect that the stateless-verifier optimization is unsound. The attack works as follows: given r, the verifier finds a non-satisfying vector x such that sumi ri C(Ai(x)) = 0, again using the notation from Theorem 5.3 in the paper [1]. For the circuits C used in most applications, it will be easy to find such a vector x. Then, the prover constructs a proof that x that sumi ri C(Ai(x)) = 0.


The proof is valid, so the verifier will accept always. To remove interaction, the Fiat-Shamir-like technique in Section 6.2.3 is probably the best way to go. We only sketched the idea in the paper (without formal analysis or proof) but if it's going to be important for your application, I'm happy to sanity-check the protocol you come up with. Another idea—the details of which I have not checked carefully—would be to modify your protocol as follows: The prover sends its data vector x to verifiers, split into k shares x1, ..., xk—one for each of the k verifiers. Each verifier holds a PRF key ki computes ri = PRF(ki, xi) and they return r = r1 + ... + rk to the prover. The verifiers store no state. The prover computes the proof pi and sends (x1, pi1), ..., (xk, pik) to the verifiers—again, one for each of the k verifiers. Each verifier computes ri = PRF(ki, xi), they jointly compute r = r1 + ... + r_k, and check the proof using randomness r. The Fiat-Shamir-like approach seems slightly cleaner to me, since it only requires a single prover-to-verifier message. Either way, please let me know if I misunderstood your question or if anything else here is unclear. [1] URL
Thanks for the nice explanation, Henry. It's perfectly clear and answers my question. It also points to something that I, for one, missed the importance of: the need for the prover to "commit" to the input shares before generating the r-dependent proof. I appreciate you pointing this out. The only requirement for making upload start not idempotent is so that the randomness r can be sent to the client. It would be nice to do away with this requirement. I think the way forward is using the Fiat-Shamir technique. NAME I'll get cracking on this and let you know when I have something for you to look at.
NAME I believe the change is something like this. Let be a hash function with range . Suppose there are verifiers. The prover proceeds as follows: Splits its inputs into shares .


For each , do: Choose blinding factor from at random. Let . Set . Derive field element from (e.g., seed a PRNG with and map the output to a field element by rejection sampling on chunks of the output). Generate the proof using and . Split into shares . For each send to the -th verifier.
Yes, this looks right to me!
As of URL, the upload start request no longer exists. When we're ready to specify Prio, we'll want to include the Fiat-Shamir approach for protocols that use joint randomness. I've noted this and am closing the issue.


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!


UTF-8 über alles.
Abstract: Explain that OSCOAP works across intermediaries and over any layer.Intro: Explain that OSCOAP works for Observe and Blockwise.Intro: Move details on replay and freshness to some other section.Terminology: Explain the references and add COSE.


You'll also need to update the last paragraph of the MTI Extensions section (currently section 8.2). Now that we're going to be down to only one client-only extension defined in this document, that whole paragraph can probably be cut in favor of a one-off note in the remaining extension's section (signature_algorithms will be the last).
So that the clients can learn about what groups a server supports. The idea here is to allow a client to offer P256 but then learn that a server supports 25519 for next time without the server having to reject.


What data can and cannot be retried safely?
That's not something that QUIC knows. HTTP does though. As advice, I don't think that this needs much more expansion, but I'd be happy to take a PR.
I'm not so sure this is a HTTP-only issue. Unlike TLS 1.3, there is QUIC data being sent under encryption, and that might have side effects.
LGTM, one nit. ("using applications" is fine, it's just a bit awkward.)


This is part of the previous pull request, but I missed it because it was interleaved with some unrelated changes.


Follow-up from
Consider the following sequence of packets being sent In our old loss recovery code (before unifying TLP and RTO, ), we used the following logic for determining if an RTO was not spurious, which would then lead to collapse of the congestion window: In the example above would be packet 14. This means that to count as a verified RTO, an ACK must acknowledge 15 or 16, but not any packets smaller or equal than 14. With , we now collapse the congestion window when is larger than 2 and we receive an ACK which leads us to declare any packet lost. In the example above this means any ACK received after sending packet 15 which declares a packet lost would suffice. Even worse, this logic already triggers if we receive the ACK immediately after sending 15, i.e. when the peer didn't even have a chance to receive it. This seems a lot more aggressive than what we had before before. Is this intentional?
This is unintentional. I belIeve Jana is intending to fix this in PR , so please take a look at that.
If I understand correctly, is a fix for and only makes the description of the constant and the pseudo code consistent.
I believe the text is now correct, but the pseudocode is still incorrect in the way you describe. I think we should introduce a largestsentbefore_congestion variable as a replacement, but I'm open to other solutions.
I'm removing design. I consider this a bug fix, but still very important.
See which I believe fixes the text.
I've been using to mark things that will result in changes that affect implementations. This would seem to fit that description. Whether you consider it worth discussing is different. If it isn't worth discussing, maybe it will just be fixed by and everything will be fine without discussion in Tokyo. WIthout the label, this won't make the change log, and that might be a problem.
Fair point, I think fixes the text, but I'll re-label this as design to ensure it's included in the changelogs.
The spurious RTO detection calls an RTO spurious if any unacked packets sent prior to the RTO are acked after the RTO.


The implication here is that any packet that was received but not acked can cause the RTO to be labeled spurious, even if there were more packets that were in fact lost. This is not always right. Consider the following example: Packets 5, 6, 7 are sent Packet 5 is received, but 6 and 7 are dropped Ack of 5 is dropped TLPs (packets 8 and 9) are sent and dropped RTO (packet 10) is sent and received ACK acks 10 and 5 Since 5 was sent prior to RTO, RTO is marked spurious. A crisp definition of spurious RTO may be useful to continue. Here's what I think is sensible: A spurious RTO is an unnecessary RTO. If the RTO timer had not gone off, things would have been fine. Based on this definition, clearly the RTO was necessary in the example, and therefore not spurious. We need to change the mechanism for detecting spurious RTOs, and I'll propose the following. An RTO is spurious if an ack is received after the RTO fires that acks only packets sent prior to the RTO. In other words, RTO is spurious if ack is received after the RTO, and (instead of , as the draft currently states).
This was recently changed because Lars ran into an issue() where the RTO'd packet was acknowledged for the first time in the same ACK as the pre-RTO packets. In that case, I think it was due to an overly aggressive MinRTO and some pretty coarse grained timers, but I think we want to declare that RTO spurious, since everything would have been fine if it hadn't been sent?
NAME : does not change the semantics substantively of what was in the draft. The intent was always to declare spurious RTO if (packet prior to RTO was newly acked). I'm proposing that we change that to (no packet sent after RTO was newly acked).
In light of , I think this is OBE?
Yes, this is OBE. Closing.


Reset stream doesn't cease retransmission.
retransmission of WTSTREAM frames on the identified stream. A receiver of WTRESET_STREAM can discard any data that it already received on that stream." This is using TCP and should not talk about ceasing retransmissions.
Very good point! Will clean up


Correct descriptions of Direct and Key Agreement Direct Change examples in the back to have "real" examples - they are JSON rather than CBOR, but that makes them shorter and easier to read.


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).


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


I realize that the specific review feedback was for the Introduction - but might we also want to "minimize" the number of WS configurations discussed in Section 4 to focus on the browser motivation?
While the third configuration is not mentioned in the introduction, all three are motivated by in-browser app use cases. So I don’t see a need to cut down the discussion in Section 4. Grüße, Carsten
: The introduction motivates the layering of COAP over WebSockets to allow it to be used in a network that only allows external access through a HTTP proxy. In fact, it is not necessary to use WebSockets to do so; HTTP CONNECT provides a tunnel in this scenario. WebSockets is a specialised protocol that allows bidirectional, stream-based transport from a Web browser -- it is effectively TCP wrapped into the Web browser's security model, to make doing so safe. Using it for other purposes (i.e., non-browser use cases) isn't really appropriate. I'd suggest either removing the WebSockets binding, or changing its motivation in the Introduction. For reference, the original URL motivation:


PR had a mistake in it, and some very confusing language. The rules for generating stateless resets was all mixed up in some complementary rules about generating packets that might trigger stateless resets. This attempts to split out the rules for generating stateless resets (minimum size is 5 + 16 = 21), and for generating packets that might trigger a stateless reset (min_cid + 22).
Do we need discussion on the fixed QUIC header bit in the triggering packet and outgoing reset packet?
NAME if you can lay out what you think the security concerns are in another issue, that would helpful. I realize that there are plenty of compromises in this design, which make this less than ideal. But first I'd like to try to understand where you think this is falling short.
Do we need discussion on the fixed QUIC header bit in the triggering packet and outgoing reset packet? Originally posted by NAME in URL
Maybe I'm misunderstanding the question, but isn't the spec is completely clear on that? A stateless reset has the first bit unset and the second bit set.
Agreed, I think this is already clear and I don't see any need to change it.
Thanks both. I just wanted to check and didn't feel like I had the brain cells to answer that. I don't like relying on the image only, but the text says "two fixed bits", and stateless reset - unlike Version Negotiation - is version-specific. So I'm closing with no action.
I believe this PR addresses the stated issue, which is that the text is unclear. However, I am still concerned about the security properties of this design.


URL in this example, it would be very stupid of the client to select version C and start another negotiation after the sever has indicated D is what it prefers. The server can again select D as preferred and there exits a potential loop. However, it is possible. What are the rule we have in the specification that stops this kind of loop?
I'm not sure that I understand this question. A client makes a choice about what version to attempt (and offer) when it creates a connection. It might learn that its versions are incompatible with a server (with a Version Negotiation packet) and try again, but that retry would be a separate action. But if the connection is successfully established, the negotiation is done.
There is at most one round of incompatible VN followed by one connection that may or may not use compatible VN to switch versions again. There is no potential for a loop here. NAME can you clarify what you meant?
The scenario i was thinking is a follows - Chosen = A, Other Versions = (A, B) -----------------> <----------------- Chosen = G, Other Versions = (G,H) ........ the draft only says the client's first flight contain This contains the list of versions that the client knows its first flight is compatible with (A,B). It does not force the client to list ALL the compatible versions, so it might not list all the compatible versions. I think, there is also no requirement on the server to list ALL the compatible versions. Now server sends back another list of compatible versions (D,C). This new list triggers the client to realise it knows about versions that are compatible (E,F), and sends it back to the client as it has not interest in D or C. That trigger the server to reply with new list of compatible version (G,H).. and this goes on. It is also possible that client made a mistake by not listing all the compatible version (well it does not have to) and as it is not interested in D or C, it wants to list (E,F) and keep in negotiating. I would like to understand the with current specification this kind of interaction is not possible and the negotiation should not go on like that.
The scenarios you describe aren't allowed: if the server performs compatible version negotiation it MUST select a that was included in the client's :
yes, but servers are allowed to do incompatible version negotiation.


in my 1st scenario, the server initiates incompatible version negotiation, the server selects D instead of C as chosen by client. The expectation here is that D will be the final negotiated version, and the version negotiation will end. But is there anything stopping the client to try to enforce it's chosen one (C) again? shall we have some to avoid this case? in the 2nd scenario, it is not possible if A, B, C,D, E,F all are compatible. if the server starts incompatible version negotiation with (C,D) and client does not find any supported version, it aborts the connection. I just realized - there is no normative text for aborting the connection attempt.. As the server expresses all the versions it support in the supported versions list, the client knows there is not point on continuing with another attempt with (E,F). Unless I am mistaken there is nothing now prohibiting the client to do so. It can continue to do so.
That doesn't make sense. The server initiates incompatible version negotiation by sending a VN packet, there's no notion of chosen version in the VN packet. There's no need for normative text when there's nothing else a client can do, are you saying the client could do something wrong as opposed to aborting due to lack of versions? The client will ignore any VN packet apart from the first one:
right, my bad. I think I have drawn the picture wrong. Server send (D,C) and the client choses C but the server choses D. does this make sense? and the main issue goes away? sniped from my previous comment. >The expectation here is that D will be the final negotiated version, and the version negotiation will end. But is there anything stopping the client to try to enforce it's chosen one (C) again? shall we have some to avoid this case? yes . and should we try to prevent it? OK, I see the client ignores, but what does happen then ? does it abort the connection attempt ? Is it possible for the client to start another connection attempt with complete new original versions and a new set of other versions?
Zahed and I discussed this first scenario offline.


In this scenario, the client indicated that it was happy with D by sending it in its Other Versions, so the client will be happy when D is negotiated even if it preferred C. If the client didn't like D, it could have removed D from Other Versions and then the connection would have negotiated C. Fair enough, this can be fixed with a small tweak - see below. Zahed and I discussed this second scenario offline as well. I wrote up to make the incompatible VN text more normative and that addresses Zahed's concern here. Now we have normative text to guarantee a failure in that scenario. If the client wants to start a separate connection attempt later, it will restart the algorithm from the top. We explicitly decided as a WG to avoid telling the client to remember information from previous connection attempts because VN packets don't carry an expiration date so caching them is fraught.
LGTM


Closed
I just read Arch and have the following NiTs which I think we should address: /Listeners by default register with multiple paths/ ought this to be: /Listeners, by default, register with multiple paths/ /A Framer is a data translation layer that can be added to a Connection to define how application-level Messages are transmitted over a transport protocol. / I think this should be (because I don’t think they are protocol specific) /A Framer is a data translation layer that can be added to a Connection to define how application-level Messages are transmitted over the transport service. / /to retransmit in the event of packet loss,/ better to avoid event here :-) /to retransmit when there is packet loss,/
I am just gonna add a few more nits here: The Listener object in figure 4 is a bit awkward, it appears as if the Listen() call appears out of thin air while per the API it gets called on the preconnection object like Initiate() and Rendezvous(). In section 4.1.1, there are 5 references to section 4.1.2, is it really necessary to have that many? Point 2 in section 4.2.3 only talks about required transport services, the same should probably be said about prohibited services, i.e. "both protocol stacks MUST NOT offer transport services prohibited by the application"
Let me add to this: Section 1: print send() and recv() in fixed-with font [HTML/XML issue only] Section 2 - Figure 1: socket() [with the brackets] looks odd in the figure title
NAME I fear framers may be specific to the underlaying protocol, e.g., for SIP slicing messages out of TCP stream whereby doing nothing for SCTP and UDP
In relation to frames I think I only asked to add /service/ instead of protocol... I don't understand how Phil's comment reacts to that
NAME I think protocol is correct here and would not change the sentence.
OK - so I think you are saying the framer depends only on the specific next protocol, rather than upon the transport service that was offered? - It is still not clear to me that this is correct.
NAME that is a fairly good question… The behaviour of the framer defiantly depends on the transport service provided (which may be a subset or superset of the transport service requested).


A framer needs to support all possible outcomes of the transport services requested It may optimize based on the protocols it actually finds, e.g., turn into a no-op with the transport preserves message boundaries. Whether the next protocol is a sufficient representation of this is unclear to me. Maybe not, if one thinks of supporting arbitrarily large messages and UDP over IPv6 with and without fragmentation…
LGTM, thanks!


…out presence of glue in zones.
No further discussion on list nor here so I will merge this.
From the dnsop list, Ralf Weber suggests the draft could more clearly state that a name server might provide an "incorrect" response because it wasn't given necessary glue records in the zone data.


In early versions of path validation, there was a requirement that PATH_CHALLENGE be sent on the same path. This is, for various reasons, either unnecessary or harmful, so we no longer have that requirement. But there was some residual text that assumed that property. This removes a paragraph citing symmetry directly, and rewords text that assumes return reachability - a property that QUIC no longer provides mechanisms for.
In , we removed the requirement that PATHRESPONSE be sent/received on the same path that PATHCHALLENGE was sent. However, there is still text in the document that relies on this assumption. In 8.5, it explains that receipt of the PATHRESPONSE on another interface doesn't cause validation to fail, because "It is possible that a valid PATHRESPONSE might be received in the future." But receipt of the PATHRESPONSE, over any interface is valid, and causes the validation to succeed. In 9.2, it suggests using path validation to demonstrate return reachability, but since PATHRESPONSE need not be sent on the same path, path validation doesn't demonstrate that.
Note that sending the response on the old path can lead to failures in "break before make" scenarios. Shall we mention that?


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.


Make the definition of descendant match the common-sense definition (you are not your own descendant), adjust the text which uses the definition. Note: this allows for a much clearer definition of the tree invariant as well.


Okay I made another pass on the text based on NAME comments, however, it didn't get any short but maybe it's slight more clear now. Please re-review! (Also I moved some paragraphs around to improve the text flow; so the PR now looks bigger than it is. So we also need to update the section title now, which is "Port Selection and Application Endpoint Discovery"?)
Applicability Sec 8: >Note that HTTP/3's ALPN token ("h3") identifies not only the version of the application protocol, but also the version of QUIC >itself; this approach allows unambiguous agreement between the endpoints on the protocol stack in use. I was going to start a discussion about this at IETF 111. I think we should think hard about this; if there are a lot of versions with small differences to the application, this could result in a ridiculous cloud of RFCs.
Is there a change to make to this document in WGLC, or is this a note to be careful in the future?
I personally don't like this linkage, and think the ALPN should just define the application. While linking the version does smooth out version negotiation, it can result in an explosion in the ALPN registry. I'll start a thread on the list about this, since I suppose it can't wait for the discussion at 111 that I was planning.
The point this was discussed already at length and the manageability document is just reflecting what has been decided for h3. So if at all you'd need to raise an issue on the h3 draft but I guess that's also too late.
I disagree that the text of the H3 draft mandates this: That is a long way from saying "roll a new ALPN for each QUIC version". Maybe everyone tacitly agrees we should roll a new ALPN, and I'm in the rough. But I'd like to confirm that.
See quicwg/base-drafts
How about rewording the sentence to reflect reality, roughly Since QUIC v1 (RFC9000) deferred defining a version negotiation mechanism. HTTP/3 (RFC-to-be-whatever) deferred deciding how it would map to other QUIC versions. HTTP/3 requires QUIC v1 and defines the ALPN token ("h3") to only apply to that version.


This solves a versioning problem at the cost of future flexibility. Application protocol mappings written for QUIC v1 or other QUIC versions may be able to benefit from version negotiation mechanisms that did not exist during the development of HTTP/3 (RFC-to-be-whatever). Coupling QUIC version to ALPN tokens is one approach but not the only approach.
I believe the text already says that this doesn't have to be applied by other application. The cited text is really only meant to described what was decided from h3 as an example. We can definitely reword this for reflect the consensus more clearly as proposed by Lucas.
Lucas, I would welcome your proposal as kicking the can down the road and not enshrining an approach that I think is bad. I would also like to continue the ALPN/versioning discussion, but it doesn't have to block the applicability draft.
I can make it shorter. Maybe not as short as NAME would have it, but still shorter :)


Discussed at 20210526 Interim. Merge.
Good point about allowing PSKs in a partial Commit!


In section 5 in this sentence the term "proxied UDP packets" is used the only time and might not be clear: How about to just say "UDP packets in HTTP datagrams"?
+1 good improvement


Appendix B.1 lists two properties as "under discussion": Bounds on Send or Receive Rate: (PR 1036 fixes the name): this is no longer under discussion, these properties exist. Cost Preferences: this is no longer under discussion, I suppose?? We don't have this in the interface draft. So I have the impression that this should no longer be an appendix, the text on Cost Preferences should be removed, and the text on Bounds on Send and Receive Rate should be moved elsewhere, and not be mentioned as "under discussion".
LGMT


NAME points out that in order to correctly forward DATAGRAMs between transports where the QUIC DATAGRAM frame isn't always available, intermediaries need the ability to parse some capsules.
CAPSULE was easier to understand when it was fully opaque. When should I choose to define a semi-opaque CAPSULE vs defining a new frame? Aren't both constructs effectively hop-by-hop?
NAME you're the one who asked for this :-) The benefit of a semi-opaque capsule is that it allows defining new capsules without having to update every single intermediary in the chain, because intermediaries forward all unknown capsules.


… but keep the requirement for future formats.
Attempts to
As input to the process, this was extremely valuable, but now that this is in WGLC, we're done with it. Does the audience of the ultimate RFC need this information? The only thing that I can see that is worth salvaging is a statement to the effect that DNS64 isn't explicitly supported.
Yes, we still need it. We have not gone to IETF Last Call and, despite what some people think, the IETF gets to change a protocol significantly during IETF Last Call. But even after that, once it is an RFC, others will want to update the RFC. It is important to keep the requirements for them as well.
Actually, we probably don't need it in the RFC as long as the one future requirement (for formats) is still there. Please see PR


Spell out origin steps more clearly Split token caching into its own section I tried having an overall "origin" and "client" section, but it didn't flow as well.


One possible resolution to ; all literals are zero-padded to full bytes.
IANA made the following observation while creating the H3 registries: While the IANA copy of the registry uses two digits throughout, the QUIC draft is similarly inconsistent about whether literal hex values have any leading zeros. Is it worth updating our hex literals to use full bytes (, , etc.) or synchonizing on some other format? We probably shouldn't synchronize on trimming, since IANA has already skewed the other way.
NAME did fix this or do we need to inform IANA also?
We should probably shoot IANA an e-mail to update the registries with leading zeroes where they hadn't already assumed them.
I'll let you do that. The only registries that are affected are in HTTP/3 and QPACK.
Fixed both in the registry and the documents.
Yeah, this is easy to understand. The tables must have been annoying.


I don't love a couple of the ways I phrased things here, so feel free to offer suggestions to improve it! modulo test vectors. (NAME it'll likely take some time to get those vectors. Do you think we should hold this document until that's done?)
This looks good modulo the open issue about incremental deployment. I don't think we need to hold the document up in order to get test vectors. Benjamin Kaduk has entered the following ballot position for draft-ietf-tls-external-psk-importer-06: Yes When responding, please keep the subject line intact and reply to all email addresses included in the To and CC lines. (Feel free to cut this introductory paragraph, however.) Please refer to URL for more information about IESG DISCUSS and COMMENT positions. The document, along with other ballot positions, can be found here: URL COMMENT: Sorry about the large volume of comments; this document is actually in pretty good shape, there are just a bunch of details that can be subtle to get exactly right. I specifically call out the note in Section 4.1 about which HKDF-Expand-Label is to be used, since that would affect the actual derived keys for DTLS 1.3 (and any hypothetical future TLS versions). Section 1 While there is no known way in which the same external PSK might produce related output in TLS 1.3 and prior versions, only limited analysis has been done. Applications SHOULD provision separate PSKs for TLS 1.3 and prior versions. To mitigate against any interference, this document specifies a PSK Importer interface by which external PSKs may be imported and subsequently bound to a specific key derivation function (KDF) and hash function for use in TLS 1.3 [RFC8446] and DTLS 1.3 [DTLS13]. [...] IIRC the main target use cases for this mechanism are for existing external PSKs (violating the "SHOULD" from the first quoted paragraph), as well as deployments that are simplified by only needing to provision a single PSK. Does it make sense to include such clarifying description here?


(Similarly, is it accurate to say that "[a]pplications SHOULD provision separate PSKs [...], but the mechanism defined in this document provides a partial mitigation for use when that is not possible"? Also, we only use the word "interference" twice in this document (this is the first instance), so it might be worth a couple more words to clarify the nature of the potential interference. Section 3 non-imported keys for TLS versions prior to TLS 1.3. Non-imported and imported PSKs are distinct since their identities are different on the wire. See Section 6 for more details. (side note?) I think the precise story here is a little subtle -- for any given key, the imported and non-imported identities are distinct, but in principle one could construct a non-imported identity that overlaps with an imported identity for a different key (and we say as much at the end of Section 7). This is vanishingly rare to happen by chance, but makes the statement as written not quite categorically true. That said, the change to the binder key derivation (§ 4.2) seems to obviate any potential consequences to such a collision (though the connection attempt would presumably fail). Endpoints which import external keys MUST NOT use either the external keys or the derived keys for any other purpose. Moreover, each IIUC, this is "MUST NOT use the keys that are input to the import process for any purpose other than the importer, and MUST NOT use the derived keys for any purpose other than TLS PSKs". Is it worth spelling it out explicitly like that? external PSK MUST be associated with at most one hash function, as per the rules in Section 4.2.11 from [RFC8446]. See Section 7 for more discussion. Does this requirement apply to the inputs to the importer process, the outputs, or both? Section 3.1 Imported PSK (IPSK): A PSK derived from an EPSK, External Identity, optional context string, target protocol, and target KDF. There is an "External Identity" that is contained within the EPSK itself; is the "External Identity" listed here distinct from that?


Section 4.1 The PSK Importer interface takes as input an EPSK with External Identity "externalidentity" and base key "epsk", as defined in Section 3.1, along with an optional context, and transforms it into a set of PSKs and imported identities for use in a connection based on target protocols and KDFs. In particular, for each supported target protocol "targetprotocol" and KDF "targetkdf", the importer constructs an ImportedIdentity structure as follows: If I understand correctly the "targetkdf" is supposed to be the KDF associated with the cipher suite(s) the derived PSK will be usable for. This is something of a divergence from RFC 8446, where we assume that the KDF will be HKDF and associate only a hash function with the cipher suite. While discussing a more generic KDF concept seems reasonable (and is directly in line with the cryptographic principles that motivate this work), I'd recommend adding a few more words somewhere in this section to clarify the relationship between the targetkdf and the cipher suite(s), probably in the paragraph that starts "[e]ndpoints SHOULD generate a compatible 'ipskx' for each target ciphersuite they offer". struct { opaque externalidentity; opaque context; uint16 targetprotocol; uint16 targetkdf; } ImportedIdentity; Should we say that this is using the TLS presentation language? ImportedIdentity.context MUST include the context used to derive the EPSK, if any exists. For example, ImportedIdentity.context may (nit?) "derive" suggests a cryptographic key derivation process, but the rest of the prose suggests that this is more a process of "identification" or "determination". Is there a more appropriate word to use? Given an ImportedIdentity and corresponding EPSK with base key "epsk", an Imported PSK IPSK with base key "ipskx" is computed as follows: epskx = HKDF-Extract(0, epsk) ipskx = HKDF-Expand-Label(epskx, "derived psk", Hash(ImportedIdentity), L) I think we need to say that the HKDF-Expand-Label used (i.e., the URL prefix) is the one corresponding to ImportedIdentity.targetprotocol.


L corresponds to the KDF output length of ImportedIdentity.targetkdf as defined in Section 9. For hash-based KDFs, such as HKDFSHA256(0x0001), this is the length of the hash function output, i.e., 32 octets. This is required for the IPSK to be of length (32 octets for SHA256, not all hash-based KDFs) The identity of "ipskx" as sent on the wire is ImportedIdentity, i.e., the serialized content of ImportedIdentity is used as the content of PskIdentity.identity in the PSK extension. The corresponding TLS 1.3 binder key is "ipskx". In RFC 8446, the "binderkey" is the output of the key schedule, but ipskx is an input to the key schedule. So I think we want to say something like "the corresponding PSK input for the TLS 1.3 key schedule is 'ipskx'". The hash function used for HKDF [RFC5869] is that which is associated with the EPSK. It is not the hash function associated with ImportedIdentity.targetkdf. If no hash function is specified, I predict that someone will mess up the hash function selection while implementing this. Perhaps we could provide test vectors for the full matrix of (EPSK Hash, targetkdf hash) pairs using SHA256/SHA384? SHA-256 [SHA2] MUST be used. Diversifying EPSK by I think we might be able to tolerate the protocol* having a strict requirement that the associated hash function is specified, and provide a recommended value that would be used by people deploying the protocol in the absence of other information. This might in some sense help future-proof the document for the scenario where SHA256 weakens or is broken and the default should change. KDFs, protocols, and context string(s) are known a priori. EPSKs MAY also be imported for early data use if they are bound to protocol settings and configurations that would otherwise be required for early data with normal (ticket-based PSK) resumption.


Minimally, that means Application-Layer Protocol Negotiation [RFC7301], QUIC RFC 8446 does not limit 0-RTT data to resumption, so I think we just want "if they are bound to the protocol settings and configuration that are required for sending early data". Also, nit: I think we usually refer to the "ALPN value" instead of just "ALPN" being configured. Section 5 If a client or server wish to deprecate a hash function and no longer use it for TLS 1.3, they remove the corresponding KDF from the set of target KDFs used for importing keys. This does not affect the KDF operation used to derive Imported PSKs. Should we also include a paragraph about how to deprecate the Hash used in deriving Imported PSKs? (It's fixed per EPSK, so, "configure a new EPSK", basically.) Section 6 Recall that TLS 1.2 permits computing the TLS PRF with any hash algorithm and PSK. Thus, an EPSK may be used with the same KDF (and underlying HMAC hash algorithm) as TLS 1.3 with importers. However, critically, the derived PSK will not be the same since the importer differentiates the PSK via the identity and target KDF and protocol. Thus, PSKs imported for TLS 1.3 are distinct from those used in TLS 1.2, and thereby avoid cross-protocol collisions. [...] As I read this I recalled that up in Section 1 we say that applications "SHOULD provision separate PSKs for TLS 1.3 and prior versions". The scenario being described here sounds like it can only occur if that SHOULD is ignored, which might be worth reiterating. We also say in § 4.1 that "external PSKs MUST NOT be imported for (D)TLS or prior versions". In light of these two observations, my best interpretation of the quoted text is that it should be equivalent to: NEW: Recall that TLS 1.2 permits computing the TLS PRF with any hash algorithm and PSK.


Accordingly, a given EPSK might be both used directly as a TLS 1.2 PSK and used with TLS 1.3 via the importer mechanism (noting that this configuration is not recommended, per Section 1), using the same KDF algorithm. However, because the TLS 1.3 importer mechanism includes an additional key-derivation step, the actual PSK used in the TLS 1.3 key schedule will be distinct from the one used in the TLS 1.2 key schedule, so there are no cross-protocol collisions possible. Note that this does not preclude endpoints from using non-imported PSKs for TLS 1.2. For some reason this line implies to me that endpoints might use imported PSKs for TLS 1.2, but this is forbidden by Section 4.1 (as quoted above). Perhaps "does not preclude endpoints from continuing to use TLS 1.2 and the non-imported PSKs it requires"? Section 7 We should probably note that any information placed in ImportedIdentity.context will be visible on the wire in cleartext, and thus that confidential identifiers from other protocols should either not be used or should be protected (e.g., by hashing) prior to use. Externally provisioned PSKs imported into a TLS connection achieve compound authentication of the provisioning process and connection. Context-free PSKs only achieve authentication within the context of a single connection. Do we need to use pskdhke to get the strong compound authentication property, or is it attainable with pskke as well? Section 10.1 I'm not sure why [QUIC] and RFC 5246 are listed as normative references. Appendix B The Selfie attack [Selfie] relies on a misuse of the PSK interface. The PSK interface makes the implicit assumption that each PSK is known only to one client and one server. If multiple clients or multiple servers with distinct roles share a PSK, TLS only authenticates the entire group. A node successfully authenticates its peer as being in the group whether the peer is another node or itself.


I think it may be useful to call out that the "multiple clients" and "multiple servers" case can occur even when there are only two endpoints that know the key (that is, when they do not have predetermined client/server roles). struct { opaque clientmac; opaque server_mac; } Context; We may not need the whole 16k to hold a MAC address, especially since this is just an example. If an attacker then redirects a ClientHello intended for one node to a different node, the receiver will compute a different context string and the handshake will not complete. Similarly to the above, this could be "a different node (including the node that generated the ClientHello)".


Currently, the "Ignoring Loss of Undecryptable Packets" section indicates that some loss can be ignored, but now that we have multiple packet number spaces, I think we can constrain the set of ignorable losses to those below the smallest acknowledged packet in a packet number space. Ignoring the loss of a subsequently sent packet was not the intent.
I might have to put in a lint for HTAB...


Good catch -- will fix. Good suggestion! We can certainly add this. As the extension is merely a hint to servers when deciding how many tickets to vend, I think this is out of scope for the document. It's intended to be once per session, and we'll add that. Also a good catch. Like other extensions that are not affected by the possibly updated ClientHello, it must not change. We need to specify the server side behavior, too. That seems reasonable to me.
Thanks! Approved pending


This doesn't go overboard and clarify non-collusion assumptions for all models. It simply states the requirement that entities with access to the attestation context and redemption context do not collude, and then generalizes somewhat for simplicity. cc NAME NAME
The architecture assumes that any two parties do not collude with each other. I think this is too strong an assumption. In particular, if the Origin does not collude with anyone else, what is the point of unlinkability of the issuance and redemption flows? Looking at the use cases, it seems that where the Attester and Issuer are distinct there is a needed non-collusion assumption between them to achieve desirable privacy, but I think the origin colluding with one of the Issuer or Attester should be fine and would be worth considering in scope. Also, in addition to the non-collusion assumption, are there any other assumptions made on the parties, such as honest-but-curious, or do we consider them to be potentially fully malicious? It would be nice to spell this out.
If the Origin colluded with the Issuer it would learn the client's identity (presumably), which would be bad. Ultimately, the desired property is that any sort of collusion that would allow the redemption context to be linked to the attestation context is prohibited. I'll try to clarify.


1: It is not clear how the protocol reacts the errors from transport layers (e.g. connection failure). The protocol will just inform apps of the events and the app will decide what to do or the protocol itself will do something? The WebSockets case is addressed by RFC6455: -and- After review with the authors, we'll append a clarification for CoAP over TCP in its Connection Health section.


The text says What does disabling mean? Does this mean mean that it is valid to set this property to "Prohibit" but still set "safelyReplayable" to "Require" on the PreConnection. Should that not be an error? This is also related to . The use of safelyReplayable for both reliable and unreliable services makes the text a bit confusing. Would it not be sufficient to state that if you do not Require Reliable Data Transfer you have to be prepared to deal with duplication?
We should remove this sentence in 4.2.5:


It's possible to negotiate the CID extension but that you want to receive an empty CID (this is how you get asymmetrical CID lengths). The current text says: CID. If an implementation receives these messages when CIDs were not negotiated, it MUST abort the connection with an unexpected_message alert. But does this mean that (for instance) you can negotiate receiving an empty CID and then switch to a non-empty? I am tempted to say "no" as I recall QUIC did.
Doing what QUIC did seems prudent ... and if I didn't know what QUIC did I think I would also lean towards disallowing switching between empty and non-empty on a live connection.


The text & struct have different names for the config ID. Use the one in the struct.


Prior to this commit the literal string "." was being rendered as the start of italics in the generated HTML doc. This commit updates the markup to escape the "*."` in the generated document. Originally reported by Joel Sing - thanks!


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.


hi NAME NAME NAME PTAnotherL, reviewed the thread and I do think an additional 9065 ref here would be helpful.


Included in the text. Maybe will include further text for
In 5.5.1: This kind of suggests that an Agent may also not know the serial number. But in creating the agent-signed-data, this number is required later on. Could we clarify perhaps the Agent MUST know the serial-number; e.g. in one of these ways: configured (as in quoted text above) discovered (in "standard" way using mDNS / DNS-SD first part of service instance name) discovered (in vendor-specific way e.g. RF beacons) other (in vendor-specific way, e.g. scan QR code of packaging) - maybe that's the same as category 1 from the Agent point of view.
Additional Note: figure 4 doesn't show the part where the Agent discovers the serial number of the Pledge. This was adding to the confusion. Maybe figure 4 can stay as is; this is just to clarify that at the start of Fig 4 the Agent MUST know the serial-number. So some small link is missing to get the complete picture.
I reopened as the initial point if the registrar-agent MUST know the serial number is not solved by the QR code reference. As the registrar-agent needs to know, which pledges he is bootstrapping, he needs the list of serial numbers in advance to be able to construct the agent signed data. Text proposed will be included into the pre-conditions described in section 5.5.1, In addition, the registrar-agent MUST know the product-serial-number(s) of the pledge(s) to be bootstrapped. The registrar-agent MAY be provided with the product-serial-number in different ways: configured, e.g., as a list of pledges to be bootstrapped via QR code scanning discovered by using standard approaches like mDNS as described in 5.4.2. discovered by using a vendor specific approach, e.g., RF beacons
Ok


This: Changes the name of the draft (I made something up, but you are free to suggest a different name) Adds venue information to the draft (working group, area, stream, github, etc...) Updates some of the boilerplate stuff (README, CONTRIBUTING, .gitignore, Makefile) Adds workflows for CI with GitHub Actions Cleans up trailing whitespace (with ) so that the build runs cleanly Updates the Gemfile (I don't use this, but I tried to make it functional for those that do) From here, you should be able to create a first submission of a draft-ietf-sframe-enc-00 by pushing a tag of draft-ietf-sframe-enc-00 (or making a new release with that name).
Spec changes look ok since they are editorial/ NAME is this ready to go?
You should be able to merge this and use it straight away, if that is what you want to do (the only thing that might need attention is the proposed filename, which I just made up).


Just some points about the new text on framers in the API draft: In 10.2 it is specified in which order multiple framers run on incoming and outgoing messages, it is however never specified what the order looks like on Start and Stop events. In 10.6, "MessageFramer.DeliverAndAdvanceReceiveCursor" appears to be missing the "Data" argument that is present in "MessageFramer.Deliver". Also in 10.6, in the second paragraph it says: When it is probably meant to say While the framer implementation is able to notify the Connection that it has finished handling a Start event (by calling MessageFramer.MakeConnectionReady), there is no such way for Stop events.
As notes for the responses to these points: If there are multiple framers, the "lowest" one (the one closest to the transport) would receive start first, and the next would get the start event when the lower one is ready. Similar for stop. Good calls on the missing data argument and the typo re application vs framer. I was thinking to use the failConnection call to complete a stop, potentially with no error?


NAME here is another try at this.
I did not realize that the intent of your text was to allow out of order processing. IMO that's off the fairway and we shouldn't allow that any more than we let you reach into the TCP stack and pull out forward messages.
NAME I don't think the comparison with TCP works - the handshake protocol is internal. We should not force a particular implementation unless there's good reason to. In this case, as explained on the list, there's potential merit of allowing out of order processing of very large handshake messages with known structure. NAME What's your opinion?
Again, this is a last minute change during Auth48, so the bar is much higher than "potential merit"
This isn't motivated by security-related reasons like , so I agree with NAME that this does not raise to the level of an AUTH48 change. I propose we land this PR and close out .
Thanks NAME NAME for considering this in the first place. As I understood NAME since this does not impact the wire-format, we can revisit once the RFC has been finalized?
Once the RFC is finalized, it's final. Changes can be requested via the , or via a new document that updates the RFC in question.
Ok, thank you. I was referring to NAME comment on the list
Yes. What I was saying is that you could just write an RFC that said "you can process out of order"
corresponding to the next expected handshake message sequence number, it MUST buffer it until it has the entire handshake message. As discussed in URL The spec mandates buffering all handshake fragments, but some implementations (e.g. GnuTLS) choose to implement simpler reassembly schemes. It has been argued by Ekr that such should be discouraged because they aren't efficient. On the other hand, as Rich Salz remarks, the choice of reassembly mechanism isn't something the peer could tell (the effects of poor reassembly performance are more retransmissions, which could also be due to poor network reliability), so it does feel like we're overspecifying things here. Weakening the MUST to a SHOULD isn't good either as it allows dropping fragments altogether. There's a tension between the desire for a concrete operational guidance, which the current text clearly provides, and a more abstract formulation along the line of "implementations MUST use a reassembly scheme ensuring forward progress".


As suggested by Ekr, taking this off the mailing list and continuing discussion here. To be clear: This has no bearing on the protocol itself, it's about how much implementation details the spec should enforce.
As mentioned on the list, I don't like the in-order qualification. I agree it's debatable whether there will be cases where it makes sense to process data out of order, but (see list again) it is not inconceivable, and I see no reason to exclude this here. I would therefore prefer to drop the in-order qualification. Hi all, Both DTLS 1.2 and DTLS 1.3 mandate: Can someone explain the underlying rationale? It seems that in the context of very large key material or certificate chains (think e.g. PQC), gradual processing of handshake messages (where possible) is useful to reduce RAM usage. Is there a security risk in doing this? It would also be useful for stateless handling of fragmented ClientHello messages. I'm sure this was discussed before but I don't remember where and who said it, but a server implementation could peek into the initial fragment of a ClientHello, check if it contains a valid cookie, and if so, allocate state for subsequent full reassembly. That wouldn't be compliant with the above MUST, though, as far as I understand it. Thanks! Hanno IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.


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.


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.


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.


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.


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.


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.


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).


The comment about how there are no guidelines about PSKs like there are about generating passwords seemed like a statement of the motivation for this draft, so I moved it to the introduction. (I was going to add a reference for the statement, but I couldn't figure out how to get the citation to compile correctly. This was the document I was going to cite, in case you think it needs it: URL)


The draft states in three places that DTLS use explicit sequence numbers, while this was true for DTLS 1.2, the sequence number in the DTLSCipherstructure is a mixture of implicit and explict. Maybe "Partly Explicit"?
Please provide me with a PR to add your name to acknowledgements.
Hi, I don’t know what PR is an abbreviation for but I guess it is not clear from my username who I am. I should probably update it, I did not intend to be anonymous :) John Mattsson, Ericsson, EMAIL


Fixes issue
Thanks for this. It's a lot clearer this way.
restricts frame type varint encoding: The relevant sentence is: This means that the restriction may not apply to frames defined by QUIC extensions (such as the frame in the Delayed Acks_ extension). Must each extension spell out its own frame type encoding rules? It would be easier to change the transport draft to extend the minimal encoding restriction to not-as-yet-specified frames as well.
I read the first sentence as applying to all QUIC frame types, core or extensions. The examples confuse the matter by explicitly mentioning the core frames. Section 19.21 contains some guidance for extension frames, adding a pointer back to the encoding rules from would be a good editorial change.
The sentence I highlighted talks about frames in this document and then these frames, effectively overriding what the first sentence may imply.
yes I think we agree :)
I think we all agree that it can be made more explicit. The first sentence says that the rule for all frame types is that they be minimally encoded. Applying that principle to all frame types defined in this document means that they get one-byte encodings. We should clarify that it's an application of the rule, not a limitation of it.
Why did we have this rule in the first place? It just seems to complicate things in unexpected ways.
NAME See . IIRC the rationale for using minimal varint encoding is that stacks that support only the standardized frames can live with a simpler dispatch scheme that takes one byte as an input (regardless of the dispatch method being a table or a switch clause or whatever). While I do not have a strong opinion regarding that requirement, I'd prefer not revisiting the discussion.
PR has been merged -- closing bug.


In preparation for feature-freeze / post-first-WGLC living, this PR removes a few issues that have been discussed and pretty much resolved. It leaves a few OPEN ISSUES that could benefit from analysis during the feature freeze.


Add the necessary internal references.
Currently, the existence test description contradicts the intended use of OptionalBoolean functions. We need to be careful if we want to make a special case for OptionalBoolean functions and not open the door to any boolean value being treated similarly.
2023-01-10 Interim: Fix text to properly handle OptionalBoolean. Make sure to indicate that an existence test from a path never gets to the actual value.
Can this issue be elaborated? What is OptionalBoolean? How does this apply to functions? Examples would be great.
Base 09 explains what OptionalBoolean is and uses it in the match and search functions. The current issue will also add some text to explain the way OptionalBoolean functions behave in filter expressions.
E.g.,
I propose a slightly more compact naming of ABNF of - and -segment, which should be more consistent between them two. is well known from LaTeX and means or there.
above is wrong (and so it is in the current spec). It needs to read ... to not allow triple dot ( :-)
NAME Wouldn't dotdot-wildcard etc. be less cryptic?
Here are some quibbles with the current ABNF (prior to PR being merged) which we can sort out after The Great Renaming:
Yes, yes. See. Fixed in I like the way this looks like now. Maybe I don't understand; can you elaborate? Fixed this (and following) in Removed in To be fixed in overall overhaul, next Yes! To be fixed in overall overhaul, next To be fixed in overall overhaul, next Fixed in Discuss this in its own issue, I'd say. Fixed in It certainly does not -- it is the subset that is actually needed for normalized paths. To stay normalized, we don't allow random other ones.
Of course ... I'm quite dispassionate here.
Please see my proposal in
With merged, we still have the expression cleanup the separate issue (enhancement) whether should be allowed, to mean
My remaining points are covered by PRs , , and .
Shouldn't be named according to all other above ?
Yes, I agree. See URL
NAME Are we ready to close this issue now the PRs have been merged or did you have more expression cleanup in mind?


The only thing that comes to my mind is standardizing on the column where the is -- this is currently rather chaotic. But that can be a new issue.
Indentation of : number of lines such indented
(And it doesn't need to be consistent, just a bit less chaotic.)
Let's make the a new issue. (I haven't got a good feel for the optimal solution.)
Before we close this issue, URL slipped through the net in my earlier PRs.
Then could resolve to either or . We would introduce an ambiguity, we already found with Json Pointer () ...
OK, with the latest blank space realignments that are part of (5e2cc85), I think we are done with this.
Ok, let's refactor the ABNF later. ... or do we need two selectors here (Ch.2.61) child-longhand = "[" S selector 1(S "," S selector) S "]" given that '1' means 'at least one'.


for
Deploy Preview for gnap-core-protocol-editors-draft ready! Explore the source changes: c7273a059b212bf18879f131a5a18d9a776a2918 Inspect the deploy log: Browse the preview:
Error Response: Editor's note: I think we will need a more robust error mechanism, and we need to be more clear about what error states are allowed in what circumstances. Additionally, is the "error" parameter exclusive with others in the return?
As a starting point, I would suggest adding these sentences The error code parameter MUST be required and its value SHOULD be limited to ASCII characters. The error code indicates that a request is malformed. The AS MUST return an HTTP 401 (Unauthorized) status code to indicate that it can't identify a client instance (the error code can be ). The AS MUST return an HTTP 401 (Unauthorized) status code to indicate that it can't authenticate a client instance (the error code can be ). The AS MAY uncover additional information about the cause of the error when it can authenticate a client instance (the error code can be , , and so on).
Addressed by , still need error codes for things like token management.
The type of the of the error property in a response is currently ambiguous. In section 3 it is defined as an and in section 3.6 it is defined as a .
NAME thanks for catching that -- looks like both "error" and "errordescription" should be added to the list of parameters. I think the intent might have been for the value of "error" to be an object with "errorcode" and "error_description" fields inside of it though, so it might be better to align things in that direction instead. Do you have thoughts on which is preferable? Interop testing of error conditions is really difficult in practice, so this is a great catch!
Yaron: The AS MUST ignore any unknown extension. Justin: I’m OK with this stance, but it needs to be consistent throughout the protocol, not just at this level. Yaron: we can actually have one policy for an AS that doesn't understand something defined in the RFC (e.g. a token binding method) vs. extensions. Unknown extensions clearly must be ignored, otherwise you cannot deploy extensions incrementally. For RFC elements, this is more nuanced.


With the guidance on extension points from and error codes from and similar, this should now be covered by the current text.


I cleaned up the language.
lgtm
Cullen wants LS groups because that is what legacy gear understands. Magnus wants to use MSID, which carries this.
Discussed in DC: will test out the LS group concept, Jonathan will send text to the list and we will discuss. Concerns are that there is a potential for mismatch between what is signaled in LS groups and what is signaled in MSID. We also need to work out what to do in the absence of LS groups.
bug 32 is prob dup of this
pinged Lennox
Given the discussion on CNAME, no one in the room at IETF90 objected to the idea that LS group was MTI.
Plan here is update draft to say that when creating the SDP, everything in PC has same CNAME, and the things in the same MediaStream get put in a LS (lipsync) group. This will mean legacy stuff that support LS will do the right thing, and legacy stuff that does not, will simply try and sync everything.
Cullen to ping Harald to get his LG regarding the comment above (ie. regarding its interaction with MSID)
Just to add some clarity here .... this is what I think we decided. All the RTP in a given PeerConection will use the same CNAME. For each stream, If a stream has more than one track, then the JSEP needs to create a lip sync group (see URL ) to put all the tracks in a given stream into the same lip sync group.
Yes. If no lipsync group from the remote side, everything is synchronized. If only some tracks in LS group, the rest are unsynchronized. (Basically, if you indicate you understand LS, we take what you give us, all synced)
MT, would you be willing to write some text here?
Who has the token here?
Just realized there could be a problem. Consider A, who does not want to sync its audio/video, and B, who wants its video to be synced. A offers a=group:LS with no mids. B has to reply with a subset of the proposed mids, by 5888 rules. Therefore B's a/v won't be synced. I don't see a good reason to require this, but 5888 is pretty clear.


The identification-tags contained in this "a=group" line MUST be the same as those received in the offer, or a subset of them (zero identification-tags is a valid subset). When the identification-tags in the answer are a subset, the "group" value to be used in the session MUST be the one present in the answer.
There's an issue with LS when using bidirectional media sections. If media stream X (from A to B) uses media sections 1 and 2, and media stream Y (from B to A) uses media sections 2 and 3, what should be the lipsync groups? Are lipsync groups unidirectional or bidirectional?
see comment above. 5888 says bidi, but that is crazy talk.
Indeed. Crazy. What is our plan of attack here then? Can we ask MMUSIC to fix this? Either by un-screwing-up a=group (which seems unlikely), by making a new grouping semantic, or by telling us that there is a better option.
JSEP reserves the right to contradict existing standards where necessary. Generally, it seems like the need for symmetry in a=group is semantic-dependent, and so fixing it later in 5888 seems possible.
So you are suggesting that we define a=group:LS as declarative: it applies to the media that is sent by the peer that includes the grouping. I can live with that, though I suspect it will cause considerable heartburn. It certainly complicates the grouping model considerably.
yes, essentially. I don't see any way to reconcile LS with reality otherwise.
Changing the semantics of existing mechanisms by declaring that they are changed without actually changing them is a dangerous process. A simpler alternative is to drop media section reuse when LS groups are present: If a particular media section is a member of an LS group, or if a MediaStream requires its tracks to be part of an LS group, don't use it for a track in the opposite direction. The legacy case of one audio section, one video section that is used in both directions will then require that we somehow turn off LS group generation.


Sections 4.1 and 4.1.3 introduce to configure an Endpoint Object. The address supplied in examples appears to be an address literal. However, Section 1.1 does not define any types explicitly associated with an internet address -- or could work, but I don't think that's the intent for these APIs, either. Section 3.2.2 does not extend this. It's unclear whether this literal is intended to support IPv6 scoped addresses as described in [RFC4007]. While this RFC describes a textual representation (possibly not in line with the goals of the API), [RFC6874] describes how to represent zone indexes in an address literal. If zone indexes are not intended to be supported, this could be clarified by, when "IPv4 and IPv6 address" is mentioned in section 4.1, also citing [RFC791] and [RFC4007] with the respective address family. If zone indexes are intended to be supported, ambiguity exists around the use of and on a Local Endpoint, where the supplied address has a zone index that does not match the supplied interface. This could be clarified by: Defining type names that represent IPv4 and IPv6 addresses in section 1.1. Specifying the properties of an address literal supported by that type (referencing [RFC791] for IPv4 and both [RFC4007] and [RFC6874] for IPv6). Clarifying in section 4.1 that "IPv4 or IPv6 address" are of the respective type described in section 1.1 when used in or . Clarifying the behavior of zone index and interface choices on a Local Endpoint in a new section 4.1.4. This may tie in to to some extent in that this is unlikely to be discoverable until is called. [RFC791]: URL [RFC4007]: URL [RFC6874]: URL
(note this is in §6.1/6.1.3 post-)
Mention that the %en0 addition to the IPv6 address is equivalent to explicitly setting WithInterface. Also mention that these are implied to be system types for addresses
Looks sane


Capitalization seems to be a problem for us. We need to make things uniform. At first, I reacted to seeing "connection" as parameters in this PR, because we use the term "Connection" to refer to a TAPS-provided connection (as opposed to a connection of the underlying system), and so, de-capitalizing the term here may look better, but it is also somewhat imprecise. This said, we do the same with other capitalized terms too, here and in the API draft - e.g., "messageContext". Should we generally agree to begin terms with a lowercase letter when they are used as parameters in code examples? I think we have this in most places, though at least the API draft has several counterexamples... e.g., the server example code: Preconnection := NewPreconnection(LocalSpecifier, TransportProperties, SecurityParameters) (..) Listener -> ConnectionReceived
From discussion on
This was a mistake. As I wanted to do this now, I noticed that all occurrences of capitalized terms as parameters are objects that are defined and used elsewhere in the code examples. For example: Preconnection := NewPreconnection(RemoteSpecifier, TransportProperties, SecurityParameters) refers to RemoteSpecifier etc., being objects that are initialized some lines above. Making them appear in lower case everywhere would be awkward, this is then a much more drastic change to our pseudocode. As a result, I think it's fine to leave things as they are, and I suggest to close this issue with no action.
Framers: What is the difference between the Final message property and the separate IsEndOfMessage event argument?
Also there, the term MessageContext could use a definition
and searching "isEndOfMessage" tells me that there is no text describing this parameter. Regarding the question, the difference should be clear: seems self-explanatory, whereas indicates that the Message carrying it is the last one of the Connection. So, this is End of the Message vs. End of the Connection.
Sounds like this needs a reference to the API doc, and change IsEndOfMessage to endOfMessage to match the API.
Probably fix with
I think this looks ok (and thanks for doing this!), but see also my comment about making things uniform wrt.


capitalization: if we merge this PR, we should also do one that does the same with the API draft.Thanks LGTM! Although I noticed another nit that can perhaps be fixed in the same PR even if not directly related to the parameter names. Regarding the capitalization I think we can merge this PR and then have a separate issue for the capitalization as we will need to fix this either way.