the main point seems to be: the spec should mention both "common types" which may even get a registry, and "private types" which probably are using a different namespace, and we could suggest one pattern for doing that.


Solves issue (from review comments by NAME : URL)
Section 4.1.3.1 - I am unclear why an OSCORE error response can be cached by an OSCORE unaware intermediate would be cached, but a success message is never going to be cached. Based on this, I don't plan to set an outer Max-Age option.
Closed in 84403c4c4 Section 4.1.3.1 - I am unclear why an OSCORE error response can be cached by an OSCORE unaware intermediate would be cached, but a success message is never going to be cached. Based on this, I don't plan to set an outer Max-Age option. In section 5.4 you have the text requestpiv: contains the value of the 'Partial IV' in the COSE object of the request (see Section 5), with one exception: in case of protection or verification of Observe cancellations, the requestpiv contains the value of the 'Partial IV' in the COSE object of the corresponding registration (see Section 4.1.3.5.1). I am unclear how/why this is different for observations. A cancelation is a message, so the IV is the request. A re-registration is a request message, any response would correspond to that request. The only interesting question has to do with updating the MID on a re-registration but not how PIVs work for this field. Section 6.1 - Is a registry needed for the leading byte of compression? Behavior if bits 0, 1, or 2 is set in the flags byte on decode? Section C - given the way that my system is implemented, it would be nice if the outputs included the first full IV to be used for both the sender and the recipient. That would allow for a test that the combination of ids and common ivs is done correctly. In my case I do not have the shared IV available for testing as I immediately or in the id.


NAME wrote: "Why is the text talking about "many properties" that can no longer be changed, instead of relying on the earlier, nice and clear distinction between Selection and Connection Properties?". => In line with the suggestion from NAME this is now changed, it says Selection Properties. NAME wrote: "Where earlier, Selection Properties were said to remain readable, now they are only queryable?". => In line with NAME answer, this PR replaces "query" with "read" in this text. NAME wrote: "Are "applied" Selection Properties still Selection Properties? Shouldn't they better be referred to using a different term?" and here, NAME suggested: "In the , we define Protocol Stack as a Transport Services implementation concept, and we talk about a certain protocol stacks providing certain features (see . Perhaps we could rephrase this part of the API draft to use that terminology, e.g., the application can query the actually used protocol stack and then know which Transport Features it supports." => I don't know how to apply this change, and it generally sounds a bit complicated to me. I think that Selection Properties should keep their name. Regarding the confusing text with the example, I removed this and I think it makes things clearer. Regarding the return type, I think I now finally understood the bigger problem. Returning a Boolean instead of a Preference should make sense and should be easy to implement (as also described in this PR). The problem is that not all Selection Properties are of type Preference. E.g., is an enumeration, representing , or . What sense does it make if this becomes only or ? Similarly, and are of type "Collection of (Preference, Enumeration)", and indeed it would make sense to expect a Collection of booleans, not a singular boolean. This PR now explicitly says that, upon reading, the Preference type of a Selection Property (not the whole Selection Property!) changes into Boolean.
MANY thanks for the proposed fix (which I committed)! I hadn't really understood the problem just from reading the issue discussion.


As , here follows a bit of feedback on the different Property types in the Interface draft, from the perspective of an academic developer who is currently attempting to follow the draft spec as closely as possible while trying to implement a path-aware transport system in a In , it says: At this point, the reader of the document could be expected to conclude the following: Selection Properties are a set of preferences for protocol/path selection that (obviously) can no longer be meaningfully changed once a connection has been established. Connection Properties are a set of "run-time preferences" for connections which could still be adjusted when a connection is already established, but should ideally already be known during protocol/path selection The text goes on to state: With this wording, the reader can now reasonably conclude that the original Selection Properties that have resulted in a given Connection should remain available during the lifetime of that Connection, perhaps in form of a copy of the original data structure. So far so straight forward. In however, this conclusion is called into question. After the text has gone on to introduce the 5 different Preference Levels, it states At this point, the reader becomes confused. Why is the text talking about "many properties" that can no longer be changed, instead of relying on the earlier, nice and clear distinction between Selection and Connection Properties? Where earlier, Selection Properties were said to remain readable, now they are only queryable? The type of a Selection Property that has been "applied" mutates from a Preference Level to become a Boolean? Are "applied" Selection Properties still Selection Properties? Shouldn't they better be referred to using a different term? So the original Selection Preferences that resulted in the current Connection are not available after all? Only the (Boolean) Properties of the chosen Protocol can be "queried"? But wait, the text goes on: This is a complicated way of saying that the values only reflect the actual Properties of the chosen Connection and (in direct contradiction to the previous paragraph) do not actually indicate whether a Selection Property has also been "applied" or not. (A Boolean only carries exactly one bit of information after all.) In other words, the Protocol Properties can be queried. The usefulness of this is probably limited however.


If we already know that our Connection is using, e.g., TCP, we don't have to issue any "queries" to know that the Connection offers reliable transport, is subject to congestion control and preserves packet ordering. (This is indeed how I have chosen to implement this. The chosen Protocol can be queried for the Properties it inherently has. In the Preconnection phase, the Selection Preferences are matched against these and any / conflict results in that Protocol being dropped from consideration.) Hoping not to be unreasonable (or somehow block-headed), I have the following suggestions Either introduce a new term for Properties that have been "applied", or Use the term "Preferences" (e.g., "Selection Preferences", "Connection Preferences") to refer to a collection of adjustable "Settings" and the term "Properties" to refer to measured or queried values that are actual Properties of underlying Connections and Protocols Go into a bit more detail about what the draft really means when talking about "querying" Properties (versus setting them), maybe even in terms of exemplary interactions with Property data structures. (After all, the draft elsewhere goes into considerable detail with it's exemplary Event-based system) Think about whether it in general would clear things up when the explicit notion of Protocol Properties as a (static) counterpoint to (adjustable) Selection Properties is introduced
(Replying as an individual and co-author) Thanks for raising this issue! Yes, this matches my understanding is well. If the later text confuses this issue for the reader, then perhaps we'll need to tweak it. I'd say that Selection Properties can no longer be changed, Connection Properties still can be changed (though maybe changing a Connection Property later would not have any effect, e.g., if Capacity Profile changes but was only taken into account when selecting a path). Perhaps the text should reflect that. For me, these are synonyms, whereby a "query" is what the application has to do in order to read the properties. Perhaps the "queried" should become "read" to avoid confusion. That is indeed how I think of it on a conceptual level, but I understand how this might confuse implementers, especially if they can't just change a data type of a property. In the , we define Protocol Stack as a Transport Services implementation concept, and we talk about a certain protocol stacks providing certain features (see .


Perhaps we could rephrase this part of the API draft to use that terminology, e.g., the application can query the actually used protocol stack and then know which Transport Features it supports. I would strongly prefer using our existing terminology to introducing yet another term. Good question. I vaguely remember discussing this, and I think folks felt like querying the Selection Properties that the application had set was not very useful at that stage. The other text you quoted indeed sounds a bit complicated and maybe it can be reworded to be clearer. Curious to hear what my co-authors and/or other TAPS participants think!
I completely second what NAME wrote. With regards to querying the Transport Features selected vs. getting the preferences provided earlier, I remember we had lengthy discussions and somewhat converged to the current state. Primary arguments ware Multiple read/query variants are confusing Original Preferences are not really useful - if you really want to read them later, keep the Preferences Object Constrained implementations don't want to be forced to store them. NAME based on these arguments, what option would you prefer a) different get/query operations of selection properties after the connection has been set up b) the current way of "mutating" preferences with clearer description in the text
Just to add: having finally gotten around to carefully reading this, I also completely agree with everything NAME wrote. This is exactly how I would have answered, and her suggestions are exactly what I think should be done to address these comments. I also agree with NAME that these were the arguments regarding querying the querying issue, and I agree with the arguments as well. The quoted text containing the example is a great catch! Such a terribly convoluted paragraph. I have a nagging feeling that this was my fault! :-(
PR tries to solve this; the PR itself contains a full explanation of my rationale for the changes. Please take a look!
Great, this looks good to me now. I think now it is simple enough that we don't need an example anymore.Looks good, one clarification suggestedWorks for me (with NAME changes). I would propose a slight rewording -> and add a hint that this exposing can also be implemented differently.


This change ensures that the "init" key pair associated to the key package is one-time-use, at least to the degree that KeyPackages are one-time-use. The init key pair is used to encrypt/decrypt the Welcome message, then never again. The main drawback is requiring the KeyPackage sender to generate an additional key pair, which requires more computation and more entropy.


Is 200 really correct? This seems like a 404 maybe? Also we should specify the body (empty).
Would a problem document be appropriate (with either a pre-existing ACME error type or a new one like "accountDoesNotExist")?
404 talks about the effective request URI, so that's not going to work. I think that a 400 would be better on the basis that the request checked, but failed (NAME suggestion is a fine enhancement). The reason you make this request is to check; and having a 4xx series code is easier to test than the absence of a header field.
Thanks NAME and NAME implemented this in the latest commit.
As discussed; this is fine.


Brendan to revise based on Rohan suggestion.
Interim 2022-05-26: Concerns around making the group_id totally random Malicious group creator can choose it malicious Federated systems get worse randomness Using AEAD.Nk depends on ciphersuite, could be awkward NAME will revise to say: Here are the requirements that group ID must satisfy If you don’t have an alternative plan, do it randomly
Group ids are signed to bind certain information to specific groups. But I can imagine a case where a user mis-uses the group id to be something like a "room title" which lets an adversary control the group id and introduces potential problems. If we can prove that it's fine for a group id to be reused, then should we get rid of group ids? If not (as I expect), then group ids need to be guaranteed to be unique [globally per signing key] and we need to specify that.
Discussed at 19 May interim. NAME to generate PR documenting fresh random value approach.
Virtual interim 2022-05-19: Agreement that some sort of uniqueness requirement is worthwhile Main question is what scope of uniqueness should be Globally? Within scope of DS? Fresh random value? Simple, but precludes application usage of the field Also could help avoid metadata leakage Client / DS should probably still check for collisions NAME to write up a PR on the fresh random value idea
Group IDs must be generated randomly by creator Clients and DS must check that group ids are unique as far as they know


Even when (EC)DHE is in use, the "supported_groups" extension is only mandatory in the ClientHello; it can be omitted from the EncryptedExtensions, as per section 4.2.6. Given that, it is not MTI for the server sending to the client, but the client must be prepared to accept the extension in EncryptedExtensions (at least to the point of not crashing or aborting the handshake), so leave the MTI text unchanged. It would be too awkward to try to express this subtlety in such a concise list.


This is a minimal section for MIME type registration of message/mls. It assumes that PR include wire_format in all MLS messages (making a format parameter unnecessary), and that all messages have the MLS version number encoded (making a version parameter unnecessary). These parameters can be added if needed.
When MLS messages are transmitted over a protocol which supports Content-Type / MIME Type negotiation, signal that the message is an MLS message. Because MLS messages are really a bag of formats today we should have a MIME type parameter which specifies the specific format included. message/mls;format={applicationgroupcontext}
This seems like a fine idea to me. Could go as a section in the protocol spec, or as a separate (small) spec.
Discussion on virtual interim: Section or separate doc? How do we handle versioning? Internal to the protocol (field in MLSMessage?) Field in the MIME type Different MIME type per version
I would prefer a short section in the protocol document. I think Internal to the protocol is cleanest. Likewise the format parameter becomes unnecessary if we add Welcome, PublicGroupState, and KeyPackage to wire_format (see issue )
NAME send a PR?
Asking for friend: would we want to define (or use) a structured syntax suffix ala ?
NAME If you mean for multiple formats, no, we have only one encoding. If someone wants to re-encode the protocol as XML or whatever, a MIME type will be the least of their troubles.
Fixed in


This text is great justification to include in a charter, but this is a protocol specification and it really doesn't add much.
It seemed like the WG wanted the document to be shorter and more specific, so this feels good.


Closes URL
Allowing the use of nonstandard port numbers in SVCB for DNS provides valuable operational flexibility, but it also creates a risk related to cross-protocol confusion attacks, in which a malicious server convinces a client to send TCP contents that can be misparsed as a different protocol by a non-TLS victim server. For example, a malicious DNS server could indicate an SNI or session ticket that can be misparsed as a command by a recipient server, and use DNS rebinding to change its own apparent IP address to the victim server. Clients would then send this server-controlled payload to the victim server. This is dangerous if the client is implicitly authorized to control the victim server (e.g. authorization by IP address). Note that only DoT and DoH (over TCP) are amenable to these attacks. QUIC Initial encryption ensures that the packet has no meaning to a recipient that is not QUIC-aware, and any QUIC-aware recipient should not be vulnerable to these attacks. We should consider ways to minimize the impact of these attacks. For example, we could require clients to restrict the value of the parameter to a small fixed list, or refer to the . Credit to NAME


Answer to issue
A first sentence says quasi-error-free is usually guarranteed thanks to redundancy, while the following sentence tends to say the opposite. Not very clear.The intro fails to clarify the targets. Among them there is "coding to recover from packet losses" (to avoid confusion with bit-error corrections), but also "coding to improve the usage of radio resource". You should also clarify better what is meant by coding: it's not a content coding (e.g., to compress a video flow) but rather a computation of linear combination of packets. Say since the begining you'll rely on RFC8406 whenever possible. Parts of the text currently in section 3 (1st paragraph) deserve to be moved here.Typo: s/to cope from/to cope with/
We have updated the introduction structure and changed the usage of coding in the whole document. We hope this is better. cf PR and PR
this is cherrypicking, not discussing link/channel FEC (Error) or ACK. the heading should really be 'of network coding schemes'. "to cover cases where where"? At the physical layer, FEC mechanisms can be exploited.-- Erasure or Error? "Based on public information, coding does not seem to be widely used at higher layers." it isn't, and that section can be reduced to just that sentence.
Vincent in item X1, 1st sentence, it suggests QUIC is a video streaming application. Change it.Fig. 2 raises a general question: it refers to upper applications that are by nature on the end-hosts. Everything is imaginable here and this is not specific to a SATCOM system. Why don't you limit yourself to the communication layers + middleware? I'm a bit confused.When you say: "Based on public information, coding does not seem to be widely used at higher layers." I guess you limit yourself to the "packetization UDP/IP + middleware" but do not consider upper applications. It's also confusing.
We think that these comments have been assessed with PR
"However, physical layer reliability mechanisms may not recover transmission losses (e.g.


with a mobile user) and layer 2 (or above) re-transmissions induce 500 ms one-way delay with a geostationary satellite" Look, forward error coding (FEC) and link ACKs are complementary on a sliding scale depending on delay/channel quality, and this is talking solely about retransmissions. In fact, link or channel FEC do recover a large number of transmission bit/symbol losses without adding extra delay.
We have clarified this point in PR


NAME suggested this. It's a simplification that should reduce errors. It prevents topics like "Hello world!", but that's probably a good thing on balance.


This was inspired by the IV computation for TLS. It may or may not make things more secure. The old behavior is easy to get by making the context IV have trailing zeros.


Added clarifying text -
" including roots of trust" from .
We should add the sentence "Normally, claims are not self-asserted by a layer or root of trust." in the section describing layered attester / layering. around line 1120?
I'd not object that. I'd be okay with "Normally, claims are not self-asserted by a root of trust."


rebased.
` The first sentence seems to say ‘you can do whatever you want’, but the second seems to say “you should sign the messages” This doesn’t seem to be about integrity; it says Evidence must be confidential. Is that actually a requirement?
I don't see where it says RATS messages have to be confidential. 'end-to-end' means between RATS roles. Which can be achieved at different nesting levels; where nesting is interpreted to mean nesting in the message (data) layers. Summary - I don't see a problem with the proposed text.
I am inclined to agree with Ned here, but we could change the first line, while we're at it. The reuse of the word "protected" used in the 1st sentence in the 2nd sentence now might make it more clear that this message protection can happen on many layers.
Ok but this PR merges into the branch instead of master. Recommend rebasing on master so that order of merge doesn't matter.


This PR removes the manifest section. The motivation is to factor the "core" Web Bundles specification to include just the minimal amount needed to support cases like subresource loading, which does not need a manifest. This and other removed sections can be defined in other documents in the future. Adapted from URL
We might want to make sure the impact of removing manifest section from the bundle format on the chromium. NAME NAME Does Chrome have any usages of manifest section? It seems doesn't use it, however, I am wondering whether there is existing use case for that, I am not aware of.
I never really understood the motivation of this section, since the primary URL response can contain a header pointing to the manifest.
Imagine the situation of application distribution, it is very useful to have a manifest section. For example, we can display the application icon without parsing the HTML of the primary URL. But I agree that the manifest section can be outside the scope of the "core" bundle specification. So removing it from the core spec looks good to me.
LGTM (just for record). Thanks for working on this.


I welcome this ... thanks.
From the side line: Do we need to add description of behavior (with a qualifier) to motivate the truly welcome attributes of the ?
A Normalized Path is just a particular kind of JSONPath query. Its only behaviour is to identify a node within the tree of nodes in a value. Or did you have some other behaviour in mind?
Oh, of course, but that formulation had never occurred to me, and it's useful. If it's not in the spec, it should be.
I meant the first of the two sentences: Here we describe the behavior of an implementation (output as response to an unspecified request that triggers the former). I just wonder if this section is a good place to describe a part of a protocol, when the topics are a) the "projection" itself and b) potential benefits (all from a data perspective).
Well, we describe the nature of what it is to implement JSONPath. Generally, in a protocol, you not only need to prescribe what is on the wire, but also what it means. That is only ever in the implementation. That doesn't mean that it describes the behavior of an implementation. E.g., in TCP, the byte stream that is transported by the protocol only ever happens in the implementation. Nothing on the wire reflects this byte stream. But describing that byte stream as the underlying model of TCP is rightly not criticized as "describing the behavior of an implementation".
The penny has just dropped: you are questioning the need for such a description rather than asking for more of the same! I agree with NAME response.
I think an important aspect that this is missing is that normalized paths are contexted to the JSON data that was queried; whereas singular paths exist independently, as does any other path. For example, the path (used in the text) is singular and can rightfully exist on its own. However it can't be normalized without querying JSON data. Once queried, the resulting normalized paths can be different based on the data. yields a normalized path of for the value yields a normalized path of for the value .
This text isn't getting into implementation behavior at all. It's specifying output and allowing for options.
Well, unforced ambiguous behavior then. Specifying output and allowing for (unrequested) options.


For instance when the SomeTool processor outputs a number 42 and the options are that it represents any base in which the symbols are generally valid (per consensus) to me would rather raise questions than answer them. I would expect these complication (extra dimensions) less inside a format but more in a "processor" role or protocol description. The latter describing expected behavior within the dynamics of some interchange. I used the term without caution. Sorry for that. In my reading of the sentence we discuss about, the consumer of such a result has to look elsewhere to find out what the processor provides as result, right? That is our normal task as tool users. However, I think we better try to not bring in such ambiguities without noting the reason outside of our mandate to change. Maybe note, that existing processors (or however we like to call these providers of jsonpath responses) display mixed behaviors (what you call options). Makes sense? If not, sorry for the noise.
Well, we do say: I wouldn't go so far to say that the Normalized Path is "contexted". You need the value to compute the Normalized Path from the query, but after that, it doesn't require context to apply it (well, they are meant to be applied to that value, but they are regular JSONPath queries). With IETF 115 raging and Glyn being offline for a couple of days, we'll probably not respond very fast the next few days; I think good points are being made here even it is not always clear how to modify the text further to fully reflect them.
I believe the PR now makes this property of Normalized Paths clear. (I'd prefer not to labour the example.)
NAME I have attempted to address your concern by making the following general statement (suggested by NAME Normalized Paths. A nodelist is defined as follows (in the Terminology section): From this, it is clear that an implementation of JSONPath may output a nodelist as a JSON array of strings, where the strings are Normalized Paths. So I have deleted the following statements, which seemed to be causing confusion: Normalized Paths instead of, or in addition to, the values identified by these paths. For example, the JSONPath expression could select two values and an implementation could output the Normalized Paths and .


(I'm not sure whether this will be acceptable to the other reviewers, so I'm going to leave the PR open until they have had a chance to review the latest version.)
Normalizing paths? What does that mean? There is no concept of "normalizing" arbitrary paths, it's pointless, there is no suggestion of that in Goessner's original article, or anywhere else that I'm aware of.
NAME Not sure if you've seen the final form of this PR, but I'm going to merge it to close off the discussion threads. We can adjust the section later if necessary.
URL begs the question of whether nodelists should have a normalized form. This would improve the interoperation, predictability, etc. of JSONPath implementations that output nodelists. Without this, JSONPath implementations which output nodelists would likely choose multiple different ways of representing nodelists. The proposal is for a Normalized Nodelist to consist of a possibly empty, whitespace separated list of Normalized Paths as in the following ABNF: Note: this proposal does not provide a normalized form for output from JSONPath implementations that output both nodelists and values.
good approach ... I would prefer a comma separated list, being able to be consumed as a JSON array without further modification ...
ohh ... and the URL as JSON strings, i.e.
I don't think we want to do this. This is not a JSONPath query, but a structure built from that. I'd like to leave structure building to JSON entirely. We are not defining the syntax of JSON, and we should avoid falling into the restatement antipattern trap. So yes, a nodelist might look like , but not because we say so, but because that is JSON syntax. We would simply say nodelists are canonically represented as JSON arrays of strings, where the strings are normatlizedpaths.
yes ... that's even better and pragmatical.
Why do they exist? The spec says nothing on the subject. If we don't have something convincing to say, why not remove them? I know we discussed this before, but as I was reading this with fresh eyes I was thinking "There's a lot of stuff here but why bother?"
The normalized path was to be used in the output. I don't think there was any other use for them.


We wanted to ensure that the output was consistent (primarily for testing/comparison purposes), so we devised the "normalized path" to ensure that paths were output in a known format. After the refactor, it basically just means that the path doesn't use the shorthand notations; all of the segments are bracketed.
The following sentence in the Normalized Paths section provides some motivation: but maybe we need to expand it along the lines of NAME comment above.
Yes, that's my recollection. Yes, Normalized Paths use only bracket notation, but bracket notation can also produce paths which are not Normalized, such as and .
I repeat my basic question: What are these things for and what benefit do they offer, and to whom? I'm not sure what "used in the output" even means. It seems to me that more motivation is needed. I'd also be OK with just removing the whole section.
Here goes... A Normalized Path plays the same role as a JSON Pointer in situations where JSONPath syntax is required instead of JSON Pointer. A Normalized Path identifies a node in a given JSON value. Given a JSONPath expression which identifies a particular node in a given JSON value, there is a unique Normalized Path which identifies the same node in the given JSON value. Software (applications, libraries, JSONPath implementations, etc.) which outputs Singular Paths identifying nodes in a JSON value can output the equivalent Normalized Paths instead. A benefit of doing this is that the behaviour of the software is then more predictable and more easily tested (because the tests need to accommodate fewer possibilities). If there are multiple implementations of the software, sharing a single test suite is made more tractable. Who does this benefit? Human or programmatic users of the software observe more predictable behaviour. People writing tests have less work to do. Sharing a test suite avoids people duplicating effort.
Normalized paths are introduced in Stefan Goessners's , and are implemented in the two most important implementations, Goessner JavaScript JSONPath, and . I assume Stefan Goessner can speak to the original motivation, and if you want to know how they are used in practice, I suggest surveying users, perhaps starting on the Jayway site. Among other uses, they are helpful for diagnostics, for discovering what a perhaps non-obvious query resolves to in terms of the individual nodes selected.


They have other uses for selecting specific nodes given a much larger query.
I think the spec needs a statement with a MUST/SHOULD/MAY about supporting these things and a clear suggestion as to what useful purpose they're designed to serve. Otherwise I seriously suggest removing them because to be honest I can't think of a single scenario where I'd use them.
I think they're intended not to be written but consumed. I agree in that I doubt anyone would write out except maybe in the context of a stackoverflow question or something. They'd just use . The point of this, though, is to be able to declare a preferred syntax that implementations should use to identify a known location in a document. It's just saying that we prefer over . (One advantage of using the bracketed syntax for normalization is that any location in a document can be written in this syntax, whereas there are restrictions on the dot syntax.) Again, I think this is most apparent in output when the implementation is returning paths to locations instead of / along with the values.
Another consideration is the spec's definition of nodelist as the output of applying a query: The following statement in the Normalized Paths section: steps into implementation detail. In the rest of the spec we studiously avoid prescribing implementation details. One way to reconcile these would be to put some non-normative text near the start of the spec which talks about implementation options for nodelist. This could then include language such as "If a nodelist is represented as a list JSONPath expressions, these SHOULD be Normalized Paths.". (But would it make sense to use "SHOULD" in non-normative text??)
I don't think that's implementation detail. It's defining what the output may be. We can talk about this in another issue if it concerns you, though.
I would say it's a statement about the representation of the abstract nodelist. A list of Normalized Paths is a string representation. Other possible representations are lists of JSON values in string form, a programming language list of nodes, etc. The choice of representation is an implementation decision. Feel free to raise a separate issue if you'd like to change the current text.
Normalized Paths ... are a concrete string presentation of nodelists (JSON text). are already used in the spec within every example table (Result Paths).


are meant as an additional / alternative output of a JSONPath query. enhance predictability and testing. might (will) be used as input for subsequent analysis / actions (removing of duplicates?). Think of piping in Unix. Especially with the last point standardizing them is essential.
Could we include a bit of Stefan's argument somewhere in the introduction to the section?
Done - see URL
Definitely the right direction. Thank you!


I believe we can merge this now as it is. If we want to add more guidance later we should open a separate issue and another PR.
This issue came up during the discussion of issue . We say that ACK or ACK_MP frames can be send over any path, however, maybe we should discuss some guidance and trade-offs. E.g. sending on the same path as the packets received also for RTT measurements; using the shortest delay path might have some performance benefits...?
I agree. We should add some guidance here. We did some experiment regarding this issue. Our finding is returning ACK on the shortest path is helpful. But the improvement is only more significant when the path rtt ratio is larger than 4:1.


As discussed on Slack, currently the text makes no mention of the case where the PUSHPROMISE arrives behind (some of) the data on the push stream itself. However, it does mention this situation for the DUPLICATEPUSH frame. This proposed change recommends buffering pushed data for an unknown PUSHID and using flow control to prevent this from being a problem. I am unsure if more text is needed (e.g., what happens if the PUSHID is never resolved (which would mean a misbehaving server)), but I think the proposed change should suffice. This is also related to issue . Thanks to NAME for his help.
LGTM. Non-normative language seems to be the best form of guidance here
the push id that links a push stream to a push promise is now an unframed varint that comes right after the stream preface. this is right now the only unframed data (except made for the unidirectional stream prefaces) in the specs and I am proposing to make that a frame as well for consistency and to simplify implementation and allow code reuse. motivation: the specs already define frames that only carry a single varint (mostly push related) max push id duplicate push cancel push and goaway! here instead we decided to leave it unframed just because we can since it is at the beginning of the stream cost: two extra bytes per push stream the text will need to specify that on a push stream this new frame (PUSH_ID ?) MUST be the first one, otherwise it is a protocol error. I am happy to put up a PR, in case we reach consensus
The varint type and length of a frame is also unframed. So you are asking to trade one unframed varint for two. Is your assertion that this is unique and difficult code to write, or that the unframed content is somehow difficult to manage?
This seems to be going back to some of the early discussion we had on a thread I can't find. I'm not against discussing things again because we have more experience. However, I don't see a compelling reason for the change. My implementation needs to parse unframed data because of the stream header and for QPACK streams. I think this change might make my implementation more complex.


Reading multiple varints requires more work: more checks to see if the stream has enough data, more checks to ensure only 1 frame sent at a specific time (this is the same as SETTINGS)
NAME those are in the frame header -- so they are part of the frame. I am not sure what your point is here then. Here I am assuming that an implementation has generic code to parse frames, and that parsing anything that is not part of a frame requires special handling. While this is implementation specific and there can definitely be counter examples, from an abstraction and consistency point of view I see no reason for doing it the way we are doing it now. (If we discount the unidirectional stream preface) I believe there should be two type of streams: framed (control, request, and push streams) and unframed (QPACK, and potentially extension streams). The push stream right now is a hybrid, that only becomes a framed stream after receiving that first PUSH_ID. If I am recalling correctly when we discussed potentially having DATA frames with zero-length to transition to unframed data, it was also considered a bit unusual. Here I am arguing that we are sort of doing the reverse here where we have an unframed stream that then transitions to framed. I think this generates complexity. And really the benefit we get is saving two bytes and one frame type. NAME I do vaguely remember that discussion and not 'wasting' frame types may have been one of the arguments when we made that decision, but that is not a problem now that we have a 62bit space for frame types.
I don't care about the cost, I care about things like having to deal with PUSH_ID (or whatever) frames in places other than the start of a push stream. And I don't believe that it is difficult to take the special-case code for pulling a varint off a partially-available stream and use that for push ID. We've not had too much trouble with that so far in our implementation.
it is definitely not difficult, but it is a special case and as any special case forces an increased complexity in the possible codepaths, even if not that big in this case. I am making my argument for the sake of consistency mostly, and for the fact that I believe it would also help to better define error handling.


With the current text, if I receive something bogus on a push stream (after the preface) I'll have to keep the stream around (because the push stream may come out of order) waiting for a PUSH_PROMISE with that ID that may never come. So I believe that framing could help error handling as well. I do not have super strong feelings about this proposal but at the same time I'd like us to try and recall what the motivations are for the current text and for making this special since it was a while back and personally I can't recall what they were.
This sounds like the case NAME is looking at. I'd argue this is a good reason for the current design, frame processing should only take place once the PUSH_PROMISE is received. But I'd like to understand how framing could help avoid errors.
I was not trying to solve the same problem as here, but I was mentioning the fact that I believe framing would slightly help in a subset of cases. Take a server with a buggy push implementation, rather than a malicious one. Something that doesn't send the PUSHID at all. On the client you'll start seeing a flow of data and you can't do anything better than parsing the first few bytes of that as a PUSHID, and basically see random IDs. With Framing, if a server forgets to send the PUSHID, it is clear at the receiver that it is a protocol error. That being said there are many other classes of bugs that may trigger the same behavior even with frames, so this is minor. NAME now, that seems like an implementation dependent claim :) as says (and I like it) a client should buffer any data after receiving the PUSHID and before it has a PUSH PROMISE for it. and that is sufficient. no mention of frames there.
Right now in draft 19 we have: Parse varint - stream type Parse varint - push ID Parse varint - frame type (HEADERS). The assertion then is, if step 2 gets skipped by the sender, the receiver will parse the HEADERS frame type as a varint expecting it to be the push ID (value 0x1, with no restriction on min or max encoding). It will then parse the HEADERS frame length as a varint expecting it to be the HEADERS frame type (length is unlikely to be 1).


Doesn't the client just blow up at that point?
It was just an example. And as I said I don't feel strongly about the error handling nit. But if you must, yes if you assume headers is the first frame after the pushid then yes you would read 0x1 which is conveniently a server initiated bidirectional stream which is not allowed anyway, so you could reject it immediately. But I find this just fortuitous. For example, one could make a counter argument: why are we framing SETTINGS at all given that it is the first message on the control stream ? We also defined it quite clearly in this table what to do with it [Certain frames can only occur as the first frame of a particular stream type; these are indicated in Table 1 with a (1).] URL Do you think there is zero value in doing that for the PUSHID as well? I personally think there is some value. Anyway, I think we are diverting this the wrong route. All I am looking for here is a good explanation for why it is defined like it is now, and I am failing to find it. As far as the implementation goes it makes little difference, and I guess it is more of a consistency problem for me. That naked varint on the wire triggers my OCD :) So instead of going back and forth like this, perhaps NAME can shed some light on the good reasons why it is this way.
+1 to levelling up, I'll take acknowledge my guilt here. But before I move on: If your at the stage of parsing QUIC STREAM frame payload, you should already know exactly what the stream ID is. Some historic points I remember: In Paris MT presented some ideas for unidirecitonal streams - URL This relates to issue URL and PR URL Push and control streams were identified then. And we were happy with reserving specific stream IDs for certain things. All non-reserved streams were server push streams. Subsequent data on the stream only makes logical sense to handle if you know what push it relates to, so those bytes go first. Roll forward some, QPACK design requires additional streams so those get reserved to. Around Kista, the topic of unidirectional stream types comes up. Without types, we make uncoordinated unidirecitonal stream extensions quite a difficult thing.


So add more bytes at the start of stream and remove reservations. The SETTINGS frame can contain a set of parameters, indeed it SHOULD contain at least one GREASE setting. A single SETTINGS frame that describes the length of all parameters is quite useful, you know when the peer has finished sending all of them. I don't see as much value for PUSH_PROMISE because you're just framing a single integer that describes its own length already.
oh gosh yeah, I confused PUSH_ID with a stream id. scratch that completely
One can imagine a scenario where we'd want to place something before the SETTINGS frame on the control stream. On the other hand, it's less likely we'd ever want anything other than the Push ID to begin the push stream.
Discussed in London; no.
Seems like a good editorial improvement.


The text in 2.1 is more complete, so we don't need this.
When I read 3.0 I was a bit confused, because when the discussion of streams takes place in section 2.1, the requirement on stream ID ordering is already mentioned, but the reminder of what the types are is fresh in the mind. Perhaps this should be revised.


You don't want to age out before you get epoch 3 because otherwise you might be dropping when you have handshake packets.
For my understanding: what is the harm of keeping the 0-RTT keys around till the end of the handshake?
"Yes, the goal is to encourage people not to keep 0-RTT keys too long, because they might not have PCS. The replay risk is essentially a non-issue, except to the extent that it might already have been replayed."


I think that the answer here is that DDR resolution is SVCB-reliant as defined in the SVCB spec. Can you make that explicit please?
says It sounds like you're saying that DDR should adopt this without adjustments. That seems reasonable to me.
Right. I sort of assumed that it was SVCB-reliant, but it doesn't say that. Certainly, this is not a case where any deviation from spec is necessary. (The more of those we have, the better.)
DDR predates when the reliant and optional terms came about, which is why it wasn’t covered. I’m not clear on why anything would need to be said here. Reliant and optional seem to be modes for the client to block on getting SVCB records or falling back and ignoring them if they don’t arrive. Discovery based on IP addresses is done with an SVCB query for URL, and no other query types are allowed for URL By definition, this only works with SVCB. That doesn’t mean that a client can’t be SVCB optional for its general operation — it just means that if SVCB is blocked or fails, you don’t get to discover the encrypted resolver. What do we need to say here that would actually benefit things?
So SVCB-optional doesn't even make sense for this specification. I was just looking for a nudge in the form of: "The resolver/client uses SVCB in a SVCB-reliant mode." Just so that there is no confusion.
Yes, optional doesn’t make sense. But I still think that the entire reliant/optional choice is orthogonal to how DDR works. These are the two lines that mention reliant mode in the SVCB spec: Both of these seem to be about client behavior for connection establishment to a hostname. It’s specifically about connecting. It doesn’t make sense to connect to URL; this is a special purpose SVCB query used for discovery, which can lead to a connection. I don’t see any requirement from the SVCB spec that protocols that use SVCB need to define themselves as “reliant” or “optional”. Is there something I’m missing there?
How is this not about connecting from the point at which you feed the name into a SVCB query? A DDR client is trying to connect to a (secure) resolver. To that end, it is making a SVCB query.


That it uses "URL" doesn't change the overall goal.
Until a client uses the SVCB query for discovery, it doesn’t know if an encrypted resolver exists that is designated. I’m not sure if saying a DDR-aware client is “SVCB-reliant” means that it will not use the unencrypted resolver for application queries until it discovers an encrypted resolver (which is not a requirement, obviously, since clients can be allowed to continue using unencrypted DNS if their local policy allows it), or it means that the connection to the discovered encrypted DNS server is SVCB-reliant, which is tautologically true since the existence of said server was only discovered via SVCB. If it’s the former, we shouldn’t say it because it’s really about client policy for allowing unencrypted DNS. If it’s the latter, I don’t see the value of adding anything, and I’m not sure it really fits the meaning of “reliant”.
I believe DDR clients' recommended behavior is exactly the behavior recommended in Section 8.2 of SVCB-DNS, quoted above. It is initially SVCB-optional, and becomes SVCB-reliant once SVCB resolution succeeds. Specifically: if you do discover an encrypted resolver, and you attempt connection, you SHOULD NOT fall back to unencrypted if that connection fails. Otherwise, you've added a downgrade vulnerability to attackers on the "transport path" (which may not be the same as the bootstrap-query path). As this is the default recommendation for SVCB-DNS, I don't think any additional normative language is strictly required. However, I think a reminder might be appropriate. This does not address the question of whether to wait for SVCB resolution before issuing any initial queries. As a practical matter, I don't think we can require that.
Okay, I agree with the behavior you describe there of being initially optional and then becoming reliant. I can try to find a place where it makes sense to reference that section.


Some definitional work for terms that were poorly used. Note that "host" in the remaining uses is strictly interpreted in the RFC 1122 sense, so I left those alone. I considered sorting the terms section differently, and might still alphabetize that, but this isn't problematic just yet.
The word "host" is undefined. If it is equal to "endpoint", it should be replaced. Otherwise, "host" should" be defined in Sec 1.2. The word "address" sometime means "IP address" and "a pair of IP address and port" in other cases. Sec 1.2 should define "address" as "a pair of IP address and port". And "IP" should be added in front of "address" which means "IP address".
fixed this.
Thank you!


I actually used the URL in the draft to clone a copy, so I think this is good to go.


what's the difference between "deactivated" and "revoked"?
Deactivated is done by the user; revoked is done by an administrator.
OK, so we need to either say that or use clearer terms :) I talked with NAME offline, and I think he's going to propose something.


Originally raised by Magnus: Section 5.2.1: o Session Information ("i="), URI ("u="), Email Address ("e="), Phone Number ("p="), Bandwidth ("b="), Repeat Times ("r="), and Time Zones ("z=") lines are not useful in this context and SHOULD NOT be included. Considering that b=CT is not useless, I am a bit surprised to see b= on this list. Yes, b=CT: is only useful is one like to provide a upper total bandwidth limitation. So, maybe some discussion of the possible choice?
This is just a mistake in 5.2.1 - we cover how to deal with it later in section 5. Prob need to remove the mention of b= here.


Adding a description to signaling options to improve readability. I have pending to update L2TP after the other issue is solved URL
Thanks, Victor. Does the text reflect the latest version of signaling/discovery split?
leaf l2tp-type { type identityref { base t-ldp-pwe-type; } description "T-LDP PWE type."; }
The type should be taken from this registry: URL
A new IANA-maintained module is created to fix this issue.


From NAME Please consider using the same wording for the title as for 6.2 and 6.1 (nit) Who is "we" in " We do have experience" ? While I share some concerns about deploying a new transport in user space as opposed to more stable and controlled kernel space, I wonder whether this paragraph is relevant in this document. Does it bring any value ? If no, then please remove it.
We'll look at the date for CUBIC being enabled by default in the Linux kernel as "experience". We'll delete the paragraph as suggested.
was fixed elsewhere.
LGTM. I'm almost sad to lose the ref to "Congestion Defense in Depth", but I guess it makes good sense, that's not a consensus position.


URL
Thanks NAME On Sat, Sep 15, 2018 at 08:51:55PM -0500, Benjamin Kaduk wrote: My apologies if I missed it when it went by, but did we ever hear more about this requirement from the proponents of externalAccountBinding? Thanks, Benjamin


Adds the overview text proposed in .
Thanks NAME !
Thanks for putting together the overview. The figures are great :-) Looks good to me with one proposition.


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


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


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


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


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


I am not sure that I agree with this as some state carries across from the first connection attempt to the second (and hopefully successfully completed) connection. (Also, I've implemented this within the same connection object. I know that other implementations differ here, so what I'm looking for is a little finesse in how this is framed.)


** Section 12.1.2.1. Would it be more precise to say: OLD The degree of protection afforded to this key material can vary by device, based upon considerations as to a cost/benefit evaluation of the intended function of the device. NEW The degree of protection afforded to this key material can vary by the intended function of the device and the specific practices of the device manufacturer or integrator.


Closes: URL
In the lookup filtering description, we talk about how href can be queried for (that it only applies in the URI form), but say nothing about anchor (to which the same applies in principle, with slightly different statements about application to the endpoints). Thanks Christer for pointing that out. As RFC6690 contains a lookup example for ?anchor=, we may want to add one here as well.


Addresses .
Refactor intro to: Use case Problem description Solution from . Hi Sean, Thanks for the follow-up. I refreshed my memory as much as I could. Please see my responses in line. Yours, Daniel Sean Turner wrote: I think I would rather take the structure: 1 - Use case 2 - Problem description 3 - Solution I am fine with whatever fits best to you. Server operators often deploy TLS termination services in locations such as remote data centers or Content Delivery Networks (CDNs) where it may be difficult to detect key compromises. Short-lived certificates may be used to limit the exposure of keys in these cases. However, short-lived certificates need to be renewed more frequently than long-lived certificates. If an external CA is unable to issue a certificate in time to replace a deployed certificate, the server would no longer be able to present a valid certificate to clients. With short-lived certificates, there is a smaller window of time to renew a certificates and therefore a higher risk that an outage at a CA will negatively affect the uptime of the service. Typically, a TLS server uses a certificate provided by some entity other than the operator of the server (a "Certification Authority" or CA) [RFC8446 ] [RFC5280 ]. This organizational separation makes the TLS server operator dependent on the CA for some aspects of its operations, for example: Whenever the server operator wants to deploy a new certificate, it has to interact with the CA. The server operator can only use TLS signature schemes for which the CA will issue credentials. To reduce the dependency on external CAs, this document proposes a limited delegation mechanism that allows a TLS peer to issue its own credentials within the scope of a certificate issued by an external CA. These credentials only enable the recipient of the delegation to speak for names that the CA has authorized. Furthermore, this mechanism allows the server to use modern signature algorithms such as Ed25519 [RFC8032 ] even if their CA does not support them. We will refer to the certificate issued by the CA as a "certificate", or "delegation certificate", and the one issued by the operator as a "delegated credential" or "DC". I think my concern has been clarified by Ilari. It was resolved by your b). I am fine with both text. works for me.


The text does not address my concern and will recap my perspective of the discussion. My initial comment was that the reference [KEYLESS] points to a solution that does not work with TLS 1.3 and currently the only effort compatible with TLS 1.3 is draft-mglt-lurk-tls13. I expect this reference to be mentioned and I do not see it in the text proposed text. If the intention with [KEYLESS] is to mention TLS Handshake Proxying techniques, then I argued that other mechanisms be mentioned and among others draft-mglt-lurk-tls12 and draft-mglt-lurk-tls13 that address different versions of TLS. This was my second concern and I do not see any of these references being mentioned. The way I understand your response is that the paper pointed out by [KEYLESS] is not Cloudflare's commercial product but instead a generic TLS Handshake proxying and that you propose to add a reference to an academic paper that discusses the LURK extension for TLS 1.2. I appreciate that other solutions - and in this case LURK, are being considered. I am wondering however why draft-mglt-lurk-tls12 is being replaced by an academic reference [REF2] and why draft-mglt-lurk-tls13 has been omitted. It seems that we are trying to avoid any reference of the work that is happening at the IETF. Is there anything I am missing ? My suggestion for the text OLD: (e.g., a PKCS interface or a remote signing mechanism [KEYLESS]) NEW: (e.g., a PKCS interface or a remote signing mechanism such as [draft-mglt-lurk-tls13] or [draft-mglt-lurk-tls12] ([LURK-TLS12]) or [KEYLESS]) with [KEYLESS] Sullivan, N. and D. Stebila, "An Analysis of TLS Handshake Proxying", IEEE TrustCom/BigDataSE/ISPA 2015, 2015.


[LURK-TLS12] Boureanu, I., Migault, D., Preda, S., Alamedine, H.A., Mishra, S. Fieau, F., and M. Mannan, "LURK: Server-Controlled TLS Delegation”, IEEE TrustCom 2020, URL, 2020. [draft-mglt-lurk-tls12] IETF draft [draft-mglt-lurk-tls13] IETF draft It is unclear to me what is generic about the paper pointed by [KEYLESS] or [REF1]. In any case, for clarification, the paper clearly refers to Cloudflare commercial products as opposed to a generic mechanism, and this will remain whatever label will be used as a reference. Typically, Cloudflare co-authors the paper appears 12 times in the 8 page paper. The contribution section mentions: """ Our work focuses specifically on the TLS handshake proxying system implemented by CloudFlare in their Keyless SSL product [6], [7] """ The methodology mentions says: """ We tested TLS key proxying using CloudFlare’s implementation, which was implemented with the following three parts: """ """ The different scenarios were set up through CloudFlare’s control panel. In the direct handshake handshake scenario, the site is set up with no reverse proxy. In the scenario where the key is held by the edge server, the same certificate that was used on the origin is uploaded to CloudFlare and the reverse proxy is enabled for the site. """ Cloudflare appears in at least references URL CloudFlare Inc., “CloudFlare Keyless SSL,” Sep. 2014, URL N. Sullivan, “Keyless SSL: The nitty gritty technical details,” Sep. 2014, URL works for me. works for me seems clearer. I suspect earlier clarifications addressed this. thanks that it way clearer. Daniel Migault Ericsson


More = better. There are a few other places that this treatment might be applied elsewhere if the editors feel that way inclined. This seemed to be the most important.
I'll do a pass for other obvious paragraphs that can be split up.


Because this document now delegates the way the keys are advertised from the RRType ESNI to HTTPSSVC shouldn't the RRType Considerations be removed from this document.


Everyone was confused by the phrasing that the API needed to provide evidence it supported the architecture. Since it's a proper component of the architecture, it doesn't really need to; that is assumed. Rather, it needs to inform the client of versions/types/etc so that the client can determine whether it supports the API. Rephrase accordingly. Fixes issue
Thanks again for the suggested text, NAME
A reviewer says, Suggestion: state that a version of the protocol should be included in the API response.
Isn't the content-type of the API response sufficient indication? That implies that we might need a new content-type if we want to make incompatible changes in a subsequent revision, but I think that is a good plan.
At the architecture level, can we state the point more clearly? Maybe better to state what the User Equipment should do if the API response doesn't make sense?
So, the fact that we've discovered the API likely means that we're interacting with the architecture -- i.e. we got there from PvD or the dhcp option. So, I'm not sure what it would mean to not support the architecture in that case. It would be a provisioning mistake, I guess? We should suggest what the UE could do in that case, though, for robustness. So, maybe mention that the API should have a content-type in the response to indicate that it is indeed a captive portal API, and then what to do if the UE doesn't recognize that?
So I think that the reviewer here was simply confused about the choice of words and phrasing. How about: A caller to the API needs to be presented with evidence that the content it is receiving is for a version of the API that it supports. For an HTTP-based interaction, such as in {{API}} this might be achieved by using a content type that is unique to the protocol.


Remove statement that the document describes the data structure in sufficient detail for implementers and describe more clearly how individual RRsets and the successive RRSig record set are identified by referencing the relevant sections in RFC's; and remove the in response to Eric Rescorla's DISCUSS point: IMPORTANT: I'm not sure that this is actually sufficient to allow an independent implementation without referring to the other documents. I mean, I think I pretty clearly can't validate this chain from the above. Similarly, although I think this is enough to break apart the RRSETs into RRs, it doesn't tell me how to separate the RRSETs from each other. I think you need to either make this a lot more complete or alternately stop saying it's sufficient.


cc NAME NAME for an extra set of eyes to check me here -- ASN.1 is not my forte. I went based on the implementation , which I think matches what Frank did , but I would definitely appreciate confirmation!
Friendly bump NAME and NAME =)
Do you have a test vector / example to make sure it matches what I believe?
NAME yeah, each includes the encoded public key ().
Example, taken from the current test vector:
Looks good to me. But yeah, ASN.1 is not the most concise nor readable format.
ASN1 matches my expectations as well.
... we should make it clear, and provide test vectors to make sure it matches. The test vector could include public keys in PEM format and then print out the expected key ID.


Generated from . cc NAME NAME NAME
These test vectors should cover the whole flow of the protocol, starting with the input and producing a output.


I think that the decision was to make this mandatory, since present-but-empty is harder to screw up.
Section 6.2 Figure 1 and others show messages as non-optional. Section 6.3.3 however states that: It seems that the message could indeed be omitted if the server doesn't need to respond with any extensions, but I may be wrong here. We should fix one of the two places though as they contradict each other.


This is an important security consideration for the re-encryption case, which doesn't appear to be covered by the current text.
Salt could be the same, but key definitely needs to be different. Requiring both to be different is best, of course.


I think this can be merged.
Fixed the problem with ':' in refs. Now merging.
Based on Stephens review
Referring to this in :
From the PR : "As explained by Krawczyk, any attack mitigated by the NIST requiment would mean that the KDF is fully broken and would have to be replaced anyway." I didn't understand "any attack mitigated by the NIST requirement", and how mitigation could imply that something is broken. As far as I understand, the statement is something like "if there is a problem deriving secret and non-secret material from the same KDF, then there is a problem with the KDF" Perhaps "an attack based on the violation of the NIST requirement is an attack on the KDF itself"?
Yes, it was likely meants to say "if any attack is mitigate" Let's reformulate according to your suggestion
I made a commit to correct spelling and grammar. I don't think we can give applications more guidance here. How to gererate e.g. private key in certificates are way outside of EDHOC, and it would anyway be hard to say something general as deployments might look very different.I did not want to say anything about randomly generated conenction ID as that is not how connection IDs is meant to be generated. They are intended to be as short as possible. An implentation is allowed to use long random bytestrings but is not recommended in general.
PR merged


Added changes to recovery as well.
By design, TCP is capable of handling late-arriving acks. If a TCP endpoint receives an ack for a byte range after declaring loss of that byte range, retransmission of that byte range is cancelled. In contrast, QUIC uses monotonically increasing packet numbers. That is definitely an improvement, but does have a downside. If loss detection is too sensitive, and if endpoints drop information regarding what had been sent in a packet at the moment that packet is declared lost, then it would not recognize the late acks. I think that we should suggest (even if not recommend) QUIC endpoints to recognize late-arriving acks, so that our loss detection can be as aggressive and as effective as TCP, if not better. (Please let me know if such text already exists. I am opening the issue because I could not find one)
I have to agree. We had to implement late acknowledgment by marking "lost" packets and retaining them. I believe that this was very helpful in reducing the amount of redundant information we send. Failing to retain packets that were marked as lost was also the cause of a bug. As the lost packet was removed from our outstanding calculation (a different value to the "in-flight" counter we use for congestion control), we believed that there were no packets outstanding and we didn't try to send anything when the next PTO fired. As the loss detection timer is shorter than the PTO timer, we believed that there was nothing to send often (and we don't check all sources of frames, which would have told us otherwise).
Agreed.
Yeah, we should have text on this if we don't already.
The resolution in introduces a new recommendation for senders, so this ought to be considered a design issue if we're happy with that resolution.
URL we have this text:
NAME Thank you for pointing that out. I missed that. I tend to think that we should adopt . As stated in my original comment, handling of late acks is the prerequisite of many of the normative requirements that exist in the recovery draft. Therefore, it is better to have a normative requirement for handling of late acks.
I'm not opposing adding new normative text. If new text is added, I think that the existing text should be aligned to it.


In the PR, it recommends 3PTO, but the recovery draft A.1 says 1RTT.
FWIW, our implementation, as of a little while ago, tracks for the current PTO. If everything is working nicely, that limits our commitment. As we are sending probes, the time lengthens so that we send a probe before discarding state. If it takes two probes to get an ACK, we won't recognize that, but we will always catch an ACK for the last set of probes. And the state commitment is minimal unless we're forced to probe.
I'll note that the PR is against transport, but this issue is tagged as recovery.
Thanks for pointing out this inconsistency, NAME I would argue that this should be a PTO, since that allows for including the RTT variance in the waiting period. Using a PTO includes the maximum ack delay as well -- which may not be necessary -- but it's convenient to use the PTO period.
I wanted to clarify my comment on the PR about believing that 1 RTT is a preferable recommendation to 3*PTO. We definitely don't want to discard this information BEFORE the packet is lost or acknowledged. But after it's been declared lost, there's no need to wait longer than the reordering window to receive an acknowledgement, because an immediate ACK will be sent when the out of order packet arrives. I tend to think an RTT is a plenty long reordering window in practice. If nothing is inflight before and nothing sent after the packet is lost AND the late immediate ACK for the reordered packet is lost, then it could take longer than the reordering window to receive an ACK, but that seems like an edge case that's not very interesting.
NAME : I've changed it to 1 PTO. We've commonly used PTO as a time period for everything else in the transport, and so it's convenient to use PTO here too. Ultimately, this is the amount of time you're holding on to packets marked as lost, so the extra time waiting for a PTO (over an RTT) really shouldn't make any measurable difference. If you still think we should say RTT, I'm fine with that.
I'm fine with PTO, and I prefer PTO above RTT.


There could be reasons where there are some packet reordering due to multiple paths being used (e.g., ECMP, clustered endpoint). In such case, the variance of latency becomes more like a constant independent of RTT. I think it is a good idea to recommend a value (i.e. PTO) that can cover such constant even if RTT is very small. PTO has that would cover that constant.
I'm not convinced I understand the rationale completely, but I'm ok with 1 PTO. I believe we should update the recovery draft in the same PR.
So, design?
We have text about this in recovery, but it's there was no normative text and it's in the appendix, so I think this is design.
Let's not thrash too much on this one.


See .
iirc there was a discussion on stuff. In general I'm ok with just NAME do you see any issue with that?
No issue, I was aware of the BCP and I think this case fits the first provision for segregating the name spaces in the Appendix B, so any one of the proposed solutions there, including yours, is fine with me.


This uses positive framing for the recommendation to use frames rather than packets. And it makes that recommendation directly, rather than implying it.
Here are three quasi-nits about S 12.2. Handshake, 1-RTT; see Section 4.1.4 of {{QUIC-TLS}}) makes it more likely the receiver will be able to process all the packets in a single pass. A packet with a short header does not include a length, so it can only be the last packet included in a UDP datagram. An endpoint SHOULD NOT coalesce multiple packets at the same encryption level. Is the implication here that you should instead pack all the frames into one packet? UDP datagram. Senders MUST NOT coalesce QUIC packets for different connections into a single UDP datagram. Receivers SHOULD ignore any subsequent packets with a different Destination Connection ID than the first packet in the datagram. Is there a valid reason to have different SCIDs? ({{packet-version}}), and packets with a short header ({{short-header}}) do not contain a Length field and so cannot be followed by other packets in the same UDP datagram. Note also that there is no situation where a Retry or Version Negotiation packet is coalesced with another packet. Should this be a MUST NOT?
Yes. See . I don't see why. It's just a fact, not a conformance requirement.
For (1) I think it would be helpful to say that.
LGTM, one suggestion.


The H3 draft is light on error handling guidance. There are number of cases for bad session IDs: The session ID is not a client initiated bidirectional stream ID The session ID refers to a stream that did not perform a WebTransport handshake The session ID refers to a stream that has been closed or reset Presumably there is no error when a DATAGRAM arrives with a bad session id -- you just drop it? For streams, perhaps HTTPIDERROR is appropriate? Issues and both refer to cases where you receive a session ID that has not been created yet. Best to keep the discussion there, but it's likely we want to allow clients/servers to buffer some of these at their own discretion rather than require an error.
For 1, I think it should be an error. For 2, we may want to clarify that the headers should be already known at that point, but it should be an error. For 3, I am not sure how to enforce this without running into potential race conditions, so we may want to leave those as-is. As for the datagrams, I think h3-datagram draft should handle this.
Thinking about 2 more, I think there's also a race condition in which a data stream could be received between the stream being open and headers being processed. I'll write up a PR for 1.
I think for 2, I meant the ID refers to a stream where the headers were known but it was not a CONNECT stream.
Discussed at IETF 111. Sense of the room for MUST close for 1, MAY close in other scenarios.


This is something we've been meaning to do for a while, and just haven't gotten around to. The Init message directly creates a group with a specified member list. The cost of group creation is O(N) DH operations for the sender, and O(1) for receivers.
This now has an OPEN ISSUE regarding the fact that we'll need to add PKE encryption for that message, as agreed out of band, let's merge this and add encryption in the next iteration.
Here's the Weekly Digest for : This week, 8 issues were created. Of these, 4 issues have been closed and 4 issues are still open. :greenheart: , by :greenheart: , by :greenheart: , by :greenheart: , by :heart: , by :heart: , by :heart: , by :heart: , by The issue most discussed this week has been: :speaker: , by It received 9 comments. This week, no pull requests has been proposed by the users. This week, 4 users have contributed to this repository. They are , , , and . This week, no user has starred this repository. This week, there have been 4 commits in the repository. These are: :hammerandwrench: Merge pull request from rozbb/mlsplaintext-signature Multiple clarifications around Framing by :hammerandwrench: Merge pull request from rozbb/hpke-encrypt Clarify how HPKE ciphertexts are computed by :hammerandwrench: by :hammerand_wrench: by # RELEASES This week, no releases were published. That's all for this week, please watch :eyes: and star :star: to receive next weekly updates. :smiley:
Here's the Weekly Digest for : - - Last week 5 issues were created. Of these, 1 issues have been closed and 4 issues are still open. :greenheart: , by :greenheart: , by :greenheart: , by :greenheart: , by :heart: , by - - Last week, 9 pull requests were created, updated or merged. Last week, 3 pull requests were opened. :greenheart: , by :greenheart: , by :greenheart: , by Last week, 1 pull request was updated.


:yellowheart: , by Last week, 5 pull requests were merged. :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by :purpleheart: , by - - Last week there were 8 commits. :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by :hammerandwrench: by - - Last week there were 2 contributors. :bustinsilhouette: :bustinsilhouette: - - Last week there was 1 stargazer. :star: You are the star! :star2: - - Last week there were no releases. - - That's all for last week, please :eyes: Watch and :star: Star the repository to receive next weekly updates. :smiley: You can also .
We have a long-standing OPEN ISSUE on creating a group with a single Init message instead of N Add messages, which would change the work of initialization from O(N log N) to O(N). I would propose roughly the following: Then the processing would be: Find the welcome that's for you Initialize a one-member tree from the Welcome Use the UserInitKeys to populate the leaves of the tree Use the DirectPath to populate the creator's direct path (as in Update)
Fixed by URL
Similarly to the for a new member, this is a PKE operation: the encryption of this message is missing from the description. This message needs to be encrypted to each client otherwise it leaks all public keys of the tree which would otherwise be protected under the common framing. A secondary question appears as a consequence. There is static key reuse for the leaves until they update, we designed HPKE so that it should be fine but I would still add an [OPEN ISSUE] for it.


Some small tweaks and fixes for issue : Move HKDF-Extract citing to a sentence and bring HKDF-Extract with it. Change the Messages arg to HashValue, as the actual hashing is stated in the definition of Derive-Secret which is passing this function a hash, not messages. (fixes issue ) More concise defining of HkdfLabel. Use the word "zeroes" instead of "0s". Edited to add: Also, appended a commit to fix an extra trailing paren.
The other possibility is that a hash of the concatenation of hashes was to be the new HashValue. Simplest change is just to make the arg for what's currently used in the definition and passed in.
NAME Rebased. Is this ok to merge now?
It never actually says that hash_value is H(messages).
This should be clear now.


Any Update proposal for the sender is redundant if the Commit includes a .
This is true, but they're also harmless, since the information in the will overwrite all of their effects. Note that: A requirement to this effect would only be binding on a committer. The receiver of a Commit MUST process all of the referenced proposals, as prescribed in the Commit. A is required if a Commit covers Updates or Removes; if a Commit covers a self-Update, then it must have a . So there's no reasn to condition on "if a is included". This seems fine for some advisory text, but not an absolute prohibition.
The way I read Section 11.2 is that the receiver should verify that the committer has followed the rules, e.g. that the commit contains all valid proposals, etc., even if that is not explicit in the list of things the receiver of a commit should do. So any requirement on the committer would also affect the receiver. So if we mandate that a committer can't include self-updates if the path is populated, then it would be implicit that the receiver checks that the committer actually followed the rules when processing a commit. I'm not sure I understand your second point. My reasoning would be that if a committer wants to do an update, they would just include a path rather than an update proposal, which is redundant anyway.
Sorry NAME I missed that there was still conversation going on here before merging . On the latter point: All I'm saying is that there is no case where there is both (a) a self-update and (b) no . So you're always in the bad scenario :) In our Wire chat, you made a good point that repeated proposals for the same leaf are invalid, and self-Updates are effectively repeats of the . Reopening, will file a fresh PR to adjust the text.


Instead of just an address / hostname, could we ask to open a tunnel to a prefix?
Tommy, can you please clarify the reasoning why this functionality is useful. Specifying the target as a subnet would to my understanding compared to a general IP tunneling address just restrict that the client will never try to send IP packets to any IP addresses outside of this subnet. And thus potentially enable serving multiple masque clients using restricted targets to share the source IP address. Is that the intention? Or is the intention here to have the masque server potentially redirect to another instance based on the target in the request?
This came up in a discussion—if we let you ask to connect to a specific hostname or address instead of all addresses (as we do today), we wondered if there was any need to connect to a subnet of addresses. This would be for connecting to an IPv6 /64, which is unique enough for a device, and doesn't require needing to assign an IP address exclusively to the client that is issuing the request.
I'm supportive of adding this if we can come up with an encoding that's not a pain to implement. For example slash with prefix length seems fine to me - the slash would be percent-encoded just like the IPv6 address colons are.
In relation to my just raised issue on source address validation if we add this functionality, I would think that the proxy would need to do destination or source address validation depending on direction of traffic to enforce the signalled aspect.


The goal here is really to provide more clarify about cardinality, if there's a better way or place to do that, that'd be fine.
I don't believe this is necessary. This idiom is well understood in TLS and this just appears to be excess verbiage.
Hiya, (As with all these PRs, I'm ok if they're not accepted...) For me, that is better than the original, but I do think we ought state the expected cardinality that implementers need to handle somewhere. I reckon it's better to not assume implementers are very familiar with SVCB as for libraries at least, the DNS stuff happens elsewhere. They will have to figure that out eventually, but better to say it somewhere explicitly I think, or we may face some important code base that doesn't handle >1 public key when it ought. Cheers, S.


As described in URL
In the Dallas presentation on “transports” you stated that the reference to proxy authentication would be restored (See URL) but it does not seem to have happened. This is an oversight. (Noted by Andy Hutton)


Connection Migration .... " it sends or it can simply send an IMMEDIATE_ACK frame" What is the intended difference between the words "it sends" or "it can simply send"?


I tried to work in what I thought were the important parts of Gorry's suggested text, PTAL if I captured everything.
It's also true that for many RF media, the performance of the forward path can be impacted by the rate of acknowledgment packets when the link bandwidth is shared.
“Severely asymmetric link technologies, such as DOCSIS, LTE, and satellite links, connection throughput in the data direction becomes constrained when the reverse bandwidth is filled by acknowledgment packets. When traversing such links, reducing the number of acknowledgments allows connection throughput to scale much further.” I’m going to push back again on this as largely wrong. Links such as DOCSIS, LTE, satellite and WiFi are asymmetric. But it’s not just that the design decisions made for these types of link resulted in asymmetric capacity (throughput limit), the designs also share the capacity, and it is important to mitigate the impact on that sharing of capacity, than purely thinking of it items of bytes/sec of capacity used. A lower feedback rate can help avoid inducing flow starvation to other flows that share resources along the path they use.On mobile devices sending data consumes RF and battery power and is more costly for a host of reasons not just asymmetry when present.
NAME -- I don't follow why you say that the statement is wrong. It seems to me that you think that the statement is inadequate. Would you mind responding here with some text you would prefer instead, and I'm happy to wordsmith and turn it into a PR?
I suggest some text something like: For some link technologies (e.g., DOCSIS, LTE, WiFi, and satellite links) transmission of acknowledgment packets contribute to link utilization and can incur significant forwarding costs. In some cases, the connection throughput in the data direction can become constrained when the reverse bandwidth is filled by acknowledgment packets. In other cases, the rate of acknowledgment packets can impact link efficiency (e.g. transmission opportunities or battery life). A lower ACK frequency can be beneficial when using paths that include such links.
NAME -- Is the text proposal in the issue enough for you to make a PR?
This is much better.


It might pay to reconcile: {{vars-of-interest}}) to be larger than the congestion window, unless the packet is sent on a PTO timer expiration; see {{pto}}. And now exceeds the recently reduced congestion window. Now, you might implement the latter using PTO machinery, but that text doesn't really suggest that in any way.
Where does this second sentence come from? I'm pretty sure I haven't implemented anything like this in quic-go. Should I?
That sentence is the the definition of the . We haven't implemented that either, and I was wondering if it truly helps.
For TCP this second case if important because as long as you don't retransmit the lost packet you will not get any ACK that acknowledges new data. I guess we don't need that for QUIC.
The second sentence was added later in , and the MUST wasn't updated, so I'll fix that. Chromium currently implements PRR(RFC6937), which is a more complex variant of this which is designed to keep the ACK clock going. I thought we discussed adding an informative reference to PRR when we added this text, and I'm not sure why we didn't.
seems to be the wrong issue you are pointed to...
Good catch, it's
I've suggested some symbolic references.


Took a stab at normative language for the rules to process Selection Properties, as discussed in . As far as I remember, we always said that outcomes have to be deterministic/consistent, so I made everything that matters a MUST. I guess our example illustrates that even given the same Selection Properties, the outcome might change depending on the situation, e.g., your path might still be Wifi but it might or might not support your preferred protocol. So, does this really have to be all MUST, or is there a SHOULD in there? Discuss. :) Also, if anyone can name a good reason why the outcome has to be deterministic, please suggest text - maybe something like "avoid surprises for the application", but this didn't really sound right, so I left it out for now.
In section 5.2. in the API doc: "Internally, the transport system will first exclude all protocols and paths that match a Prohibit, then exclude all protocols and paths that do not match a Require, then sort candidates according to Preferred properties, and then use Avoided properties as a tiebreaker. Selection Properties that select paths take preference over those that select protocols. For example, if an application indicates a preference for a specific path by specifying an interface, but also a preference for a protocol not available on this path, the transport system will try the path first, ignoring the preference." This sounds rather like an example algorithm that should maybe go into the implementation doc instead? Or is there any part of this that we need to specify normatively in order to ensure that all systems implement the same?
This goes back to issue on "conflicting policies". At the time, we decided that there must be a deterministic outcome, therefore, text was added to both the API and the Implementation document, see . If we keep it that way, perhaps the text here should point out that the goal is to resolve conflicting policies, so we achieve a deterministic outcome.
Ah okay, thanks for the background info; missed that. I think we need to use normative language here then. Maybe also a separate subsection makes this more prominent.
This reads to me like the rules for processing polices rather than an example algorithm. I think it is part of the API... Normative language would be good and a stronger opening that explains why the rules exist.


I don't think a separate subsection would make this a better read - this fits fine as it stands, as an intro to the transport property specification IMO. Regarding normative language, that's a separate discussion. So, can we close this issue?
Agree that we don't need a separate subsection. I can try to tweak the beginning of this part a bit to explain why the rules exist as NAME suggested. Regarding normative language - we definitely have it in the API draft, right? So why not have the discussion on it here as well? if we're serious about deterministic outcomes, I guess the whole thing needs to be a MUST, right?
Sorry, true, that normative language debate was about the arch draft, and we definitely have it in the API draft. So yes, let's discuss it here. I also think a MUST would make sense.
So the order of filtering out require/prohibit is not important (outcome is the same) - making the order a MUST does not make sense. Also, first sorting by preference and then filtering has the same outcome as doing it the other way around. the only thing we need to say is that filtering MUST happen and sorting SHOULD happen.
ok - I have to admit I didn't think this through, I just agree that we want a deterministic outcome from this.
Why did we require a deterministic behavior in first place? Does this prevent TAPS implementations from running experiments like Apple did with TCP SACK and ECN? Does this prevent probabilistic path probing?
This was discussed in the TAPS BoF? ... I thought it was about developers being assured that X will happen if they choose Y and not finding the ground shifting as they use the interface.
Interim: Prefers and avoids allow the implementation to decide the ordering and weighting; require and prohibit are the only hard requirements. Applications should be able to cope with any possibility that isn't prohibited. Likely should add implementation text to say how preferences weight racing.
During the interim discussion, we found that was too strict and limiting, so we opted for another approach that moves the selection algorithm to the Implementation draft. I'm preparing another PR implementing these changes.
The text that ended up in the implementation draft is not fully consistent with the racing text, opening a new issue for this and closing this issue.
LGTM, merging this. thanks, Theresa!This reads good to me.


Regarding the request for text, I don't have any ideas... but I think this could be fine as it stands? Needs more eyes though.


We need an IANA considerations section even if we make no requests of them. It's just part of the process and the section can be removed during the final publication phase.