Preference is of type Boolean, with "true" indicating that the Selection Property has been applied.  For types Integer and Numeric, special values can be defined per property; it is up to implementations how these special values are represented (e.g., by using -1 for an otherwise non-negative value). interface <del> Set (Preference, Enumeration) </del>  <del> Empty set (not setting a preference for any interface) </del>  This property allows the application to select any specific network interfaces or categories of interfaces it wants to "Require", pvd <del> Set (Preference, Enumeration) </del>  <del> Empty set (not setting a preference for any PvD) </del>  Similar to interface instances and types (see prop-interface), this property allows the application to control path selection by underlying transport security protocols.  When not specified, these algorithms should use known and safe defaults for the system.  Parameters include: ciphersuites, supported groups, and <del> signature algorithms. </del>  Pre-Shared Key import: Used to install pre-shared keying material established out-of-band.  Each pre-shared keying material is

I should have said: I approve this, modulo the changes requested by NAME
Thanks for incorporating my suggested changes. I think this can be merged now.

Preference is of type Boolean, with "true" indicating that the Selection Property has been applied. <ins> Tuple: An ordered grouping of multiple value types.  In this this document, it is written as a list in brackets, e.g., "(Enumeration, Preference)" The composition of types and their order depends on the property and is fixed for the property.  The actual representation is implementation-dependent. Collection: An unordered grouping of one or more values of the same type.  The actual representation, e.g. as a set or an array, is implementation-dependent. </ins> For types Integer and Numeric, special values can be defined per property; it is up to implementations how these special values are represented (e.g., by using -1 for an otherwise non-negative value). interface  <ins> Collection of (Preference, Enumeration) </ins>  <ins> Empty (not setting a preference for any interface) </ins> This property allows the application to select any specific network interfaces or categories of interfaces it wants to "Require", pvd  <ins> Collection of (Preference, Enumeration) </ins>  <ins> Empty (not setting a preference for any PvD) </ins> Similar to interface instances and types (see prop-interface), this property allows the application to control path selection by underlying transport security protocols.  When not specified, these algorithms should use known and safe defaults for the system.  Parameters include: ciphersuites, supported groups, and  <ins> signature algorithms.  These parameters take a collection of supported algorithms as parameter. </ins> Pre-Shared Key import: Used to install pre-shared keying material established out-of-band.  Each pre-shared keying material is


will only happen if the underlying protocol stack supports reliability and, with it, such notifications.  8. Data is sent and received as Messages, which allows the application

addresses However, we now have this path change event but it seems we actually don't have an interface to the access the path object to figure out what exactly changed...?
So the point is that we don't have an interface anymore to configure when and if a new subpath should be opened (or closed) for multipath transports, so I guess we need a way to provide the respective information to the application in order to potentially implement some logic there. We can separate this out into two events if we are sure that these are the only two cases where we would want to trigger the application.
You say "I guess" and "potentially", which gives me the impression that you also don't know what that logic would be. I tend towards not including control over subpaths (or information about them, which may only be useful if the application can also exercise some control) unless we have a clear idea about how an application should use this. or was there consensus already on adding such information? In this case, I'm not going to fight it, but clearly that's much more than just addressing . I didn't follow this particular discussion back when it happened, but there has to be a reason for RFC 6897 only being Informational... I've seen others presenting MPTCP APIs but somehow these things never made it into a standards recommendation. Maybe there's agreement somewhere that such logic should be placed below the application, not inside? Then that logic also seems more in line with TAPS to me.
Maybe I misunderstand?, I think this seems like rather MP centric thinking. There are other events, we talked on the call about an MPS change, and I am sure some people will wish to see ICMP events, etc. I am hopeful we can evolve to have more signals ... if we have an interface that can supply the events and so apps can expect to eat these. So I think for me at least this is at best a reason come in the event, splitting this into multiple events seems a bad idea. Gorry
sec 7.1.9. We're going to need an event for MTU changes. These can't simply be Send errors because the Sent event might go first, or the transport might be sending a probe with padding that doesn't correspond to a message.
So does this mean MTU of the interface or PMTU of the path? It seems simple to add an event for interface MTU changes. For the PMTU, this raises a few questions before we add: (i) I can see the motivation for an event for a decrease in PMTU, and that seems relatively easy to add ... and could also return the new upper limit (ii) Would the same also be true of an increase in the PMTU? If so, it could be helpful if the upper layer probably says how "large" it is interested in using - e.g., DPLPMTUD has the notion of MAX_PLPMTU as an upper bound on probing.
PMTU of the path. I don't have a strong opinion on increases, but I would probably have an event for increases and not bother with the maximum. An unnecessary increase notification seems less expensive than another bit of API to specify the max.
Just add a path changed event to the application (similar to the one in implementation).
Add event to Section 7.3?
Just to be sure: This is a Path Changed Event, not a specific event relating to PMTU size.
New text looked good, I think this issue has been resolved.
closed this.
LGTM

will only happen if the underlying protocol stack supports reliability and, with it, such notifications. <ins> 7.3.3. This event notifies the application when at least one of the paths underlying a Connection has changed.  Changes occur on a single path when the PMTU changes as well as when multiple paths are used and paths are added or removed, or a handover has been performed. </ins> 8. Data is sent and received as Messages, which allows the application


Connection to be congestion controlled or not.  Note that if a Connection is not congestion controlled, an application using such a Connection SHOULD itself perform congestion control in accordance <del> with RFC2914, RFC2119.  Also note that reliability is usually combined with congestion control in protocol implementations, </del>  rendering "reliable but not congestion controlled" a request that is <del> unlikely to succeed. </del>  5.2.10. reused, e.g., to create another Listener. Listening continues until the global context shuts down, or until the <del> Stop action is performed on the Listener object: After calling Stop(), the Listener object can be disposed of. </del>  The ConnectionReceived Event occurs when a Remote Endpoint has established a transport-layer connection to this Listener (for 7.1.8. <del> maxSendRate / maxRecvRate </del>  Numeric (with special value "Unlimited") / Numeric (with special <del> value "Unlimited") </del>  <del> Unlimited / Unlimited </del>  This property specifies an upper-bound rate that a transfer is not expected to exceed (even if flow control and congestion control allow higher rates), and/or a lower-bound rate below which the application <del> does not deem a will be useful.  These are specified in bits per </del>  second.  The special value "Unlimited" indicates that no bound is specified. All of the below properties are optional (e.g., it is possible to specify "User Timeout Enabled" as true, but not specify an Advertised User Timeout value; in this case, the TCP default will be used).  7.2.1.

, . Partially addresses .
sec 7.2 perhaps I'm not thinking of this correctly, but should there be a way to query the peer-offered user timeout?
This looks protocol-specific (it's not a generic transport function). QUIC could let you query it in a protocol-specific property. Proposing moving to the QUIC mapping doc.
I agree with addressing this in the QUIC mapping doc, but for clarification: this is protocol-specific already (it's about a protocol-specific TCP property), and I added a clarification that the API calls reflect the API specified in Section 3 of RFC 5482 (which doesn't include this functionality). => I agree that allowing to query the peer's UTO might be useful, but it's probably not worth adding more text for this, as I also suspect that nobody will implement this for TCP anyway (even the underlying logic from RFC 5482 isn't widely available either AFAIK). If someone does, they are still free to allow querying whatever they like ... but IMO, we shouldn't make this document longer with more protocol-specific elements than we absolutely need to include.
Can we close the Peer user timeout with no-action?
I temporarily gave this a "discuss" label to see if it provokes people to have a 1-minute chat about closing this. This didn't happen, so now I just closed it.
sec 7.1.8 This section is missing a reference to minSendRate and minRecvRate
sec 6.2 "After Stop() is called, the Listener can be disposed of." I don't understand the difference between calling URL() and simply disposing of the object. Does this imply that there is a URL() that allows a configured listener to resume?
We should just not talk about "disposing" here. Just remove the sentence.
Object disposal implies a language with synchronous destruction, something we can't assume. For something garbage collected, you'd need an explicit close method because you don't know when the object will be destroyed.
sec 5.2.9 It would be helpful to say "Applications that neither prohibit nor require congestion should query the result and disable their own congestion control if present in the transport"
Interesting, but we need to be careful in what we say. It seems safe, but not performant to do CC at multiple layers, and if it's done at a lower layer performance might be improved by not replicating the function at a higher layer...
Link to UDP guidelines document. Just mention that there are performance implications of multiple CC loops; don't just say "disable CC".

Connection to be congestion controlled or not.  Note that if a Connection is not congestion controlled, an application using such a Connection SHOULD itself perform congestion control in accordance  <ins> with RFC8085, RFC2914, RFC2119.  Also note that reliability is usually combined with congestion control in protocol implementations, </ins> rendering "reliable but not congestion controlled" a request that is  <ins> unlikely to succeed.  If the Connection is congestion controlled, performing additional congestion control in the application can have negative performance implications. </ins> 5.2.10. reused, e.g., to create another Listener. Listening continues until the global context shuts down, or until the  <ins> Stop action is performed on the Listener object. </ins> The ConnectionReceived Event occurs when a Remote Endpoint has established a transport-layer connection to this Listener (for 7.1.8.  <ins> minSendRate / minRecvRate / maxSendRate / maxRecvRate </ins> Numeric (with special value "Unlimited") / Numeric (with special  <ins> value "Unlimited") / Numeric (with special value "Unlimited") / Numeric (with special value "Unlimited") </ins>  <ins> Unlimited / Unlimited / Unlimited / Unlimited </ins> This property specifies an upper-bound rate that a transfer is not expected to exceed (even if flow control and congestion control allow higher rates), and/or a lower-bound rate below which the application  <ins> does not deem it will be useful.  These are specified in bits per </ins> second.  The special value "Unlimited" indicates that no bound is specified. All of the below properties are optional (e.g., it is possible to specify "User Timeout Enabled" as true, but not specify an Advertised User Timeout value; in this case, the TCP default will be used). <ins> These properties reflect the API extension specified in Section 3 of RFC5482. </ins> 7.2.1.


4.1.1. This is an example of how an application might listen for incoming <del> Connections using the Transport Services Interface, receive a </del>  request, and send a response. 4.1.2. <del> This is an example of how an application might connect to a remote application using the Transport Services Interface, send a request, and receive a response. </del>  4.1.3. the remote peer.  This boolean becomes false when "Timeout for aborting Connection" (see conn-timeout) is used.  7.3. During the lifetime of a connection there are events that can occur

I found the relationship between streams and connections to be extremely murky throughout the draft, and left it not really sure how I would control a streamed transport. Section 6.4 hints suggests that opening additional streams is an alternative implementation of Clone() for transports that can do so. Does this imply that if the peer stream limit does not allow new streams, the transport should open a connection instead? How does SetNewConnectionLimit() in Sec 6.2 relate to streamed transport -- are there two levels of listener: a stream listener and a connection listener? How would opening "stream listeners" relate to the maximum number of streams the peer could open (i.e. do I have to call listen() 8 times to allow the client to open 8 streams)? Or are there no stream listeners and these "connections" just sort of appear? Skimming the -impl draft, I can see there's some text here but it is not fitting together for me. There are at least three streamed transports and it would be helpful to explain how the API conceptualizes this, perhaps in a new section.
To clarify, Listen() is called once and keeps receiving streams within the NewConnectionLimit. The main thing to clarify is how the NewConnectionLimit applies to streams of a multiplexed transport. We could look at having a limit of connections per endpoint in a group from a listener.
Add a property to section 7.1.
Also make sure to have an early section being very explicit about the overall interaction model.
In section 4.1, we could add an example for explicit group management via clone, etc.
Sigh, I will never self-assign an issue again before its discussion :-) but it's ok... I'll do it

4.1.1. This is an example of how an application might listen for incoming  <ins> Connections using the Transport Services Interface, and receive a </ins> request, and send a response. 4.1.2.  <ins> This is an example of how an application might open two Connections to a remote application using the Transport Services Interface, and send a request as well as receive a response on each of them. </ins> 4.1.3. the remote peer.  This boolean becomes false when "Timeout for aborting Connection" (see conn-timeout) is used. <ins> 7.2.4. groupConnLimit Numeric (with special value "Unlimited") Unlimited This property controls the number of Connections that may arrive from a peer as new members of the Connection's group.  Similar to SetNewConnectionLimit(), this limits the number of ConnectionReceived Events that will occur, but constrained to the group of the Connection associated with this property.  In case of a multi- streaming transport, this takes the role of a limit on the number of allowed streams. </ins> 7.3. During the lifetime of a connection there are events that can occur


used, are organized within a single namespace.  This enables setting them as defaults at earlier stages and querying them in later stages: <del> Connection Properties can be set on Preconnections </del>  Message Properties can be set on Preconnections, Connections and Messages connection.  Using the same default values for independent Transport Services implementations can be beneficial when applications are ported between different implementations/platforms, even if this <del> default could lead to a connection failure, as, for example, an application needs to be explicitly designed to support a connectionless mode.  In this case, the application can recognize the failure and explicitly specify a different set of Protocol Selection Properties that result in a usable protocol.  If default values other than those recommended below are used, it is recommended to clearly document any differences. </del>  5.2.1. Connection.  The connections within a group are "entangled" with each other, and become part of a Connection Group.  Calling Clone on any of these Connections adds another Connection to the Connection Group, <del> and so on.  Connections in a Connection Group generally share Connection Properties.  However, there may be exceptions, such as "Priority (Connection)", see conn-priority.  Like all other </del>  Properties, Priority is copied to the new Connection when calling Clone(), but it is not entangled: Changing Priority on one Connection does not change it on the other Connections in the same Connection The Message Properties could be inconsistent with the properties of the Protocol Stacks underlying the Connection on which a given <del> Message is sent.  For example, a Connection must provide reliability to allow setting an infinite value for the lifetime property of a Message.  Sending a Message with Message Properties inconsistent with the Selection Properties of the Connection yields an error. </del>  Connection Properties describe the default behavior for all Messages on a Connection.  If a Message Property contradicts a Connection that were specified regarding the delivery of Messages that the application has already given to the transport system.  For example, if reliable delivery was requested for a Message handed over before <del> calling Close, the transport system will ensure that this Message is indeed delivered.  If the Remote Endpoint still has data to send, it cannot be received after this call. </del>  The Closed Event informs the application that the Remote Endpoint has closed the Connection.  There is no guarantee that a remote Close Abort terminates a Connection without delivering any remaining data: A ConnectionError informs the application that: 1) data could not be <del> delivered after a timeout, or 2) the other side has aborted the Connection.  There is no guarantee that an Abort will indeed be signaled. </del>  10. Connection. No events will occur on a Connection after it is Closed; i.e., <del> after a Closed<> event, an InitiateError<> or ConnectionError<> on that connection.  To ensure this ordering, Closed<> will not occur on a Connection while other events on the Connection are still locally outstanding (i.e., known to the interface and waiting to be dealt with by the application).  ConnectionError<> can occur after Closed<>, but the interface must gracefully handle all cases where the application ignores these errors. </del>  11.

, , , . Partially addresses . A few comments: : Kyle's comment addressed ("Connection Properties can be set on Preconnections" fixed to "Connection Properties can be set on Preconnections and Connections") : I don't think the sentence explaining what an application could do upon an establisment error is necessary. I removed it, and now the text should be clearer. : All Connection Properties but "Priority (Connection)" are entangled. This is now clearly stated, not mentioned as an example. : Great catch. I now replaced this with an example that talks about ordering (clearly, requiring ordering from UDP will have to fail). : Reworded all the bits you point out, hopefully it's all clearer now. : first, there was a broken sentence, which seemed to miss "will not occur", so I added this. Then, I removed the last sentence which had the contradictory "ConnectionError<> can occur after Closed<>, ..." statement.
contradicts itself in one paragraph: It seems like Closed<> can and should be it: the stack should refuse any further interaction with userspace for this connection after that point.
says: The transport system can't ensure that: it can ensure that either the message is delivered before clean shutdown or the connection will be broken without a clean shutdown. Later, it says: "Deliver" in the context of transports is a term of art that means "the stack handed the data over to the application". The local endpoint has no way of knowing when or if this has happened: the remote endpoint will happily ACK packets until the rxbuf is full, without delivering a single byte of data to the application. What is the actual condition under which this will fire? I think this wants to be more general, because this will happen (e.g., in TCP) even if a MITM sends a RST. Maybe just "the connection is otherwise broken".
Why? Even an unreliable connection can block forever if congestion control is in place. Maybe a better illustration is: what should the TTL on a UDP message be? Is there a maximum? If so, how do you know what it is or specify it? Maybe a better example is warranted here.
"Entangled" appears eight times in the doc and its effect is never precisely defined. The doc should specify in an easily-consumable format (e.g., a table, but not necessarily a table) exactly which properties are shared between cloned connections and which aren't.
I am having difficult parsing:
: "Although Connection Properties (see Section 7.1) can be set during pre-establishment, they may be changed later." Four sentences later: "Connection Properties can be set on Preconnections"
Unrelated, but about the same text: I notice something weird here, regarding compilation. Looking at https://ietf-URL I see: ... which is broken at the end. However, looking at URL I see: They are used to inform decisions made during establishment and to fine-tune the established connection. The behavior of the selected protocol stack(s) when sending Messages is controlled by Message Properties (see {{message-props}}). ... which is much better. Since the last manual commit is 2 days ago, this must be a strange compilation mistake.
PR has addressed Kyle's point - so this is now about something else. Please see my comment above.
The file is the correct copy. We can close this.

used, are organized within a single namespace.  This enables setting them as defaults at earlier stages and querying them in later stages:  <ins> Connection Properties can be set on Preconnections and Connections </ins> Message Properties can be set on Preconnections, Connections and Messages connection.  Using the same default values for independent Transport Services implementations can be beneficial when applications are ported between different implementations/platforms, even if this  <ins> default could lead to a connection failure when TCP is not available. If default values other than those recommended below are used, it is recommended to clearly document any differences. </ins> 5.2.1. Connection.  The connections within a group are "entangled" with each other, and become part of a Connection Group.  Calling Clone on any of these Connections adds another Connection to the Connection Group,  <ins> and so on.  "Entangled" Connections share all Connection Properties except "Priority (Connection)", see conn-priority.  Like all other </ins> Properties, Priority is copied to the new Connection when calling Clone(), but it is not entangled: Changing Priority on one Connection does not change it on the other Connections in the same Connection The Message Properties could be inconsistent with the properties of the Protocol Stacks underlying the Connection on which a given  <ins> Message is sent.  For example, a Protocol Stack must be able to provide ordering if the msgOrdered property of a Message is enabled. Sending a Message with Message Properties inconsistent with the Selection Properties of the Connection yields an error. </ins> Connection Properties describe the default behavior for all Messages on a Connection.  If a Message Property contradicts a Connection that were specified regarding the delivery of Messages that the application has already given to the transport system.  For example, if reliable delivery was requested for a Message handed over before  <ins> calling Close, the Closed Event will signify that this Message has indeed been delivered.  If the Remote Endpoint still has data to send, it cannot be received after this call. </ins> The Closed Event informs the application that the Remote Endpoint has closed the Connection.  There is no guarantee that a remote Close Abort terminates a Connection without delivering any remaining data: A ConnectionError informs the application that: 1) data could not be  <ins> delivered to the peer after a timeout, or 2) the Connection has been aborted (e.g., because the peer has called Abort).  There is no guarantee that an Abort will indeed be signaled. </ins> 10. Connection. No events will occur on a Connection after it is Closed; i.e.,  <ins> after a Closed<> event, an InitiateError<> or ConnectionError<> will not occur on that connection.  To ensure this ordering, Closed<> will not occur on a Connection while other events on the Connection are still locally outstanding (i.e., known to the interface and waiting to be dealt with by the application). </ins> 11.


The transport services API resolves names internally, when the Initiate(), Listen(), or Rendezvous() method is called to establish a <del> Connection.  The API explicitly does not require the application to resolve names, though there is a tradeoff between early and late binding of addresses to names.  Early binding allows the API implementation to reduce connection setup latency, at the cost of potentially limited scope for alternate path discovery during Connection establishment, as well as potential additional information leakage about application interest when used with a resolution method (such as DNS without TLS) which does not protect query confidentiality. </del>  The Resolve() action on Preconnection can be used by the application to force early binding when required, for example with some Network and fallback or re-establishment is supported in the transport system.  These communication activities are not different from what is used today.  However, the goal of a TAPS transport system is to support such mechanisms as a generic service within the transport layer.

I would reword this text in §5.1: such that the tradeoff is listed in a (new) privacy considerations section, leaving the description of the reduced connection setup latency in early binding here as a functional justification.
LGTM (note: accept 1 nit fix before pressing Merge)

The transport services API resolves names internally, when the Initiate(), Listen(), or Rendezvous() method is called to establish a  <ins> Connection.  Privacy considerations for the timing of this resolution are given in privacy-security. </ins> The Resolve() action on Preconnection can be used by the application to force early binding when required, for example with some Network and fallback or re-establishment is supported in the transport system. <ins> The interface explicitly does not require the application to resolve names, though there is a tradeoff between early and late binding of addresses to names.  Early binding allows the API implementation to reduce connection setup latency, at the cost of potentially limited scope for alternate path discovery during Connection establishment, as well as potential additional information leakage about application interest when used with a resolution method (such as DNS without TLS) which does not protect query confidentiality. </ins> These communication activities are not different from what is used today.  However, the goal of a TAPS transport system is to support such mechanisms as a generic service within the transport layer.


Message by passing the same MessageContext, until the endOfMessage flag is delivered or a ReceiveError occurs.  All partial blocks of a single Message are delivered in order without gaps.  This event does <del> not support delivering discontiguous partial Messages. </del>  If the minIncompleteLength in the Receive request was set to be infinite (indicating a request to receive only complete Messages),

says: What happens if a ReceivedPartial event is dispatched on an unreliably connection, but the rest of the message never shows up? Is it the case that another call to Receive will result in two events being sent: Received (or ReceivedPartial) for the new message, and a ReceiveError for the original message? Or can two messages effectively be interleaved and delivered in whatever order the constituent packets arrive?
Could you elaborate on the error case that's on your mind? Because it's unclear to me - I would say that ordering obviously needs to be preserved within a message, while inter-message ordering is a different issue (controlled by the msgOrdered Message Parameter). How is this not clear from saying that delivering discontiguous partial Messages is not supported?
Let's say you send the following: M1 M2 M3 N1 N2 N3 where M=M1.M2.M3 is one message and N=N1.N2.N3 is another message. The receiver subsequently gets: M1 N1 N2 N3 My reading of the draft is that the receiver will see ReceivedPartial ReceivedPartial ReceivedPartial Received If M2 and M3 subsequently arrive, it sounds like the receiver will never get ReceivedPartial or Received because "this event does not support delivering discontiguous partial Messages." But what makes the receiving TAPS logic decide not to wait for M2 or M3 and to start delivering N?
This is not how I would have interpreted the sentence. It talks about the message itself being discontiguous - so, e.g., delivering M1 followed by M3 would never happen. I don't see a reason why a different message couldn't be delivered, in pieces or not, after a ReceivedPartial call - every receive call comes with a message context, so the messages can be separated. I can try to make this clearer, maybe by adding an example like yours here to the draft....

Message by passing the same MessageContext, until the endOfMessage flag is delivered or a ReceiveError occurs.  All partial blocks of a single Message are delivered in order without gaps.  This event does  <ins> not support delivering discontiguous partial Messages.  If, for example, Message A is divided into three pieces (A1, A2, A3) and Message B is divided into three pieces (B1, B2, B3), the ReceivedPartial may deliver them in a sequence like this: A1, B1, B2, A2, A3, B3, because the messageContext allows the application to identify the pieces as belonging to Message A and B, respectively. However, a sequence like: A1, A3 will never occur. </ins> If the minIncompleteLength in the Receive request was set to be infinite (indicating a request to receive only complete Messages),


Boolean <del> true </del>  <del> If true, it specifies that the receiver-side transport protocol stack only delivers the Message to the receiving application after any existing previous ordered Message that was passed to the same Connection via the Send Action. </del>  If false, the Message is delivered to the receiving application without preserving the ordering.  This property is used for protocols Boolean <del> true </del>  When true, this property specifies that a Message should be sent in such a way that the transport protocol ensures all data is received Enumeration  This enumerated property specifies the application's preferred tradeoffs for sending this Message; it is a per-Message override of the Capacity Profile connection property (see prop-cap-profile). This property specifies that a message should be sent and received as a single packet without network-layer fragmentation, if possible. <del> Attempts to send a message with this property set to a size greater than the transport's current estimate of its maximum packet size ("singularTransmissionMsgMaxLen") will result in a "SendError".  When used with transports supporting this functionality and running over IP version 4, the Don't Fragment bit will be set. </del>  8.2.

I'm not 100% sure, but I believe the DF bit applies only to intermediate hops, not to the originating machine. E.g., if you have DONTFRAG set on your socket (or at the system level via pmtud) and shove 60K into a sendto() call, the kernel will still happily chop your datagram into multiple <=1500 octet packets. So, the text in §8.1.3.9 is probably misleading.
I'm not sure if this makes the text misleading? The text only says that "a message should be sent and received as a single packet without network-layer fragmentation, if possible." It may not be possible... there's also this sentence: "When used with transports supporting this functionality and running over IP version 4, the Don't Fragment bit will be set." - consider the first half of the sentence: the functionality is constrained to being offered only over transports that provide this precise functionality.
I think the text is literally correct, but misleading in that it implies a level of actionability that doesn't appear to be in evidence. Unless you have a means to know path MTU, you can't adjust your message length to avoid fragmentation or drop, so what good does this do other than result in drops vs. path fragmentation in IPv4? This will have zero effect on IPv6, for instance.
I'm confused about the confusion. What is being asked?
I think I'm asking for an example of where this property would make a difference to the wire image, other than in the DF-set case on IPv4 where intermediate hops will drop rather than fragment.
I think that this is really mainly about DF / IPv4. But, if you think of a protocol like SCTP which stuffs messages into packets, this protocol could theoretically decide that message X should not be placed such that the first half of it goes into packet 1 and the next half into packet 2, but that packet 1 should just be shorter and the whole message X should go into packet 2 instead. This is transport-layer fragmentation, not network-layer fragmentation, though. Perhaps "network-layer" should be removed from the text? This should be safe to do as long as we don't make any promises.
I don't think we should conflate transport segmentation of data with network-layer fragmentation. These have different purposes. A source host still has the choice to fragment at the network-layer to the PMTU, by the way, even when DF is set - as in IPv6. Protocols like STUN might use this to control which packets are sent with fragmentation at the sender to the PMTU, and which carry control packets to probe for a larger PMTU.
Sure the host can at the network layer anyway; we're not giving any guarantees against that. Fine not to conflate - but then the semantics of the text in §8.1.3.9 really only translates into: "in case of IPv4, DF=1". I think this is fine - it seems Kyle wants more, but why? Or should the text more bluntly say "IPv4 DF=1" perhaps?
Michael, that's basically what I'm arguing. The only lever TAPS has is over intermediate hop behavior on IPv4, reducing the whole property to "sets DF=1 on IPv4". I also agree with Gorry re: segmentation vs. fragmentation. Do we need text re: segmentation for protocols like SCTP and QUIC?
The minset part for the transport layer thing is called "request not to bundle messages"; the minset appendix currently identifies that the "No Fragmentation" message property conflates this with network layer fragmentation. I suggest that I'll fix this, by: changing the "No Fragmentation" text a little bit, just to more bluntly state that this is really only about IPv4 DF adding a Message Property that has just the transport-layer "request not to bundle messages" semantics. That should do the trick, I believe.
Shouldn't the default value for every message property basically be "inherit", i.e., from the connection? : This is a bit awkwardly worded. If this is supported for both reliable and unreliable transports (unclear?), then: For reliable transports, this means that this message will not be delivered to the application until all previous ordered messages on the connection are delivered. For unreliable transports, this means that any message prior to this one in ordering but received subsequently will not be delivered to the application.
Multiple things here. Default: interesting idea, I tend to say "yes". About §8.1.3.3: This is meant to support both reliable and unreliable transports - why this unclear (why wouldn't it support both)? IIRC this was me, borrowing the wording from SCTP which also covers both of these cases (reliable and unreliable). I like your description (at least the one for reliable transports), but I think it's good to be explicit about the relationship to the Send Action. How about this, maybe simpler to read and still generic:
URL be preserved on delivery via Receive<> events for all Messages... ?
We got us a deal! :-) Seriously, this is better and clearer, thanks! Will fix
Seeing the number of this issue, it's clear to me that you chose the wrong issue when you wrote "For the love of Satan".
Just a note regarding : you said that the default for every message property should basically be "inherit"; checking them carefully one by one showed me that this is only a reasonable decision for three of them: Ordered, Reliable Data Transfer (Message) and Message Capacity Profile Override. E.g., a default of using less than a full checksum doesn't and probably shouldn't exist anywhere. Any default other than "False" for "Final" (last Message of the connection) really doesn't make a lot of sense (only the application would know that it has only one Message to send). ... and so forth.
You are technically correct, which is the best kind of correct. I basically meant that message properties that are used to override the same property at the connection level should default to "inherit".
Looks like these issues have been addressed in this PR

Boolean  <ins> the queried Boolean value of the Selection Property "reliability" (prop-reliable) </ins>  <ins> The order in which Messages were submitted for transmission via the Send Action will be preserved on delivery via Receive<> events for all Messages on a Connection that have this Message Property set to true. </ins> If false, the Message is delivered to the receiving application without preserving the ordering.  This property is used for protocols Boolean  <ins> the queried Boolean value of the Selection Property "reliability" (prop-reliable) </ins> When true, this property specifies that a Message should be sent in such a way that the transport protocol ensures all data is received Enumeration <ins> inherited from the Connection Property "connCapacityProfile" (prop-cap-profile) </ins> This enumerated property specifies the application's preferred tradeoffs for sending this Message; it is a per-Message override of the Capacity Profile connection property (see prop-cap-profile). This property specifies that a message should be sent and received as a single packet without network-layer fragmentation, if possible.  <ins> This only takes effect when the transport uses a network layer that supports this functionality.  When it does take effect, setting this property to true will cause the Don't Fragment bit to be set in the IP header, and attempts to send a message with this property set to a size greater than the transport's current estimate of its maximum packet size ("singularTransmissionMsgMaxLen") will result in a "SendError". 8.1.3.10. noTransportFragmentation Boolean false When set to true, this property requests the network layer at the sending endpoint to not fragment the packets generated by the transport layer.  When running over IPv4, setting this property to true will also cause the Don't Fragment bit to be set in the IP header.  When this property is set, an attempt to send a message size greater than the transport's current estimate of its maximum packet size (singularTransmissionMsgMaxLen) will result in a SendError. This only takes effect when the transport and network layer support this functionality. </ins> 8.2.


other, and become part of a Connection Group.  Calling Clone on any of these Connections adds another Connection to the Connection Group, and so on.  "Entangled" Connections share all Connection Properties <del> except "Connection Priority", see conn-priority.  Like all other </del>  Properties, Connection Priority is copied to the new Connection when calling Clone(), but it is not entangled: Changing Connection Priority on one Connection does not change it on the other Connections in the same Connection Group.  It is also possible to check which Connections belong to the same Connection Group.  Calling GroupedConnections() on a specific Connection returns a set of all Connections in the same group. 8.1.2.1. The Message Framer object can be added to one or more Preconnections <del> to run on top of transport protocols.  Multiple Framers may be added. If multiple Framers are added, the last one added runs first when framing outbound messages, and last when parsing inbound data. </del>  The following example adds a basic HTTP Message Framer to a Preconnection:  8.1.2.2. When sending Messages, applications can add Framer-specific key/value

How do framers behave in connection groups? I.e. do all connections share one framer object or does the framer object get duplicated when a connection gets cloned? If it does get duplicated, does it keep its current state? This might mostly be an implementation detail but I think it should be mentioned in section 6.4 of API.
Interim: same type of framer is plausible default (but new instances), but in general a framer should be per connection. State is not shared across connections. Bigger problem: framers are added to preconnections, not connections, so how is this done with cloning? (perhaps: add list of framers as parameter added to the clone call)
I've thought about it, and Idon't think we actually have a bigger problem here: On an initiated Connection/ConnectionGroup, the provenance of the Framers is Preconnection.AddFramer() -> Preconnection.Initiate(). On a Listener, the provenance of the Framers is Preconnection.AddFramer() -> Preconnection.Listen() -> Listener.Clone(). In a Rendezvous situation, there is (unless I'm missing something) always a Preconnection from which a Framer can ultimately be inherited.
In §8.1.2 ¶3, the doc says: but this doesn't seem to be conceptually compatible with the text at the top of §8.1.2.1, which says: I think the way most developers would think about this is as a pipeline: you feed data into the top-level framer with Send, which then percolates downward through the pipeline to the bottom-level framer, which then sends it to the transport.
I think this should be easy to address, by rephrasing: as: ... BUT "call each other" is surely a terrible way to put this, and there must be a way to say this cleanly and neatly, in line with how the code really goes. THIS, I suspect, is a very simple thing for NAME to do, and hence I assigned it to him.

other, and become part of a Connection Group.  Calling Clone on any of these Connections adds another Connection to the Connection Group, and so on.  "Entangled" Connections share all Connection Properties  <ins> except "Connection Priority" (see conn-priority) .  Like all other </ins> Properties, Connection Priority is copied to the new Connection when calling Clone(), but it is not entangled: Changing Connection Priority on one Connection does not change it on the other Connections in the same Connection Group. <ins> The stack of Message Framers associated with a Connection are also copied to the cloned Connection when calling Clone.  In other words, a cloned Connection has the same stack of Message Framers as the Connection from which they are Cloned, but these Framers may internally maintain per-Connection state. </ins> It is also possible to check which Connections belong to the same Connection Group.  Calling GroupedConnections() on a specific Connection returns a set of all Connections in the same group. 8.1.2.1. The Message Framer object can be added to one or more Preconnections  <ins> to run on top of transport protocols.  Multiple Framers may be added to a preconnection; in this case, the Framers operate as a framing stack, i.e. the last one added runs first when framing outbound messages, and last when parsing inbound data. </ins> The following example adds a basic HTTP Message Framer to a Preconnection: <ins> Since Message Framers pass from Preconnection to Listener or Connection, addition of Framers must happen before any operation that may result in the creation of a Connection. </ins> 8.1.2.2. When sending Messages, applications can add Framer-specific key/value


Group.  As noted in groups, this property is not entangled when Connections are cloned, i.e., changing the Priority on one Connection in a Connection Group does not change it on the other Connections in <del> the same Connection Group.  See priority-in-taps. </del>  7.1.3. 7.1.9.  The following generic Connection Properties are read-only, i.e. they cannot be changed by an application. <del> 7.1.9.1. </del>  zeroRttMsgMaxLen before or during Connection establishment, see also msg- safelyreplayable.  It is given in Bytes. <del> 7.1.9.2. </del>  singularTransmissionMsgMaxLen Packet Size (MPS) as described in Datagram PLPMTUD I-D.ietf-tsvwg- datagram-plpmtud. <del> 7.1.9.3. </del>  sendMsgMaxLen This property represents the maximum Message size that an application can send. <del> 7.1.9.4. </del>  recvMsgMaxLen the remote peer.  This boolean becomes false when "Timeout for aborting Connection" (see conn-timeout) is used. <del> 7.2.4. groupConnLimit Numeric (with special value "Unlimited") Unlimited This property controls the number of Connections that may arrive from a peer as new members of the Connection's group.  Similar to SetNewConnectionLimit(), this limits the number of ConnectionReceived Events that will occur, but constrained to the group of the Connection associated with this property.  In case of a multi- streaming transport, this takes the role of a limit on the number of allowed streams. </del> 7.3. During the lifetime of a connection there are events that can occur

… and move the group limit connection property to the right place (it was misplaced). Note that section 8.2.7 ("Priority in TAPS") already clarifies that a Connection Priority choice doesn't guarantee a certain outcome; this just adds another sentence in the paragraph describing the Connection property to make it clearer (less easy to miss).
Looks ready to merge to me.

Group.  As noted in groups, this property is not entangled when Connections are cloned, i.e., changing the Priority on one Connection in a Connection Group does not change it on the other Connections in  <ins> the same Connection Group.  No guarantees of a specific behavior regarding Connection Priority are given; a transport system may ignore this property.  See priority-in-taps for more details. </ins> 7.1.3. 7.1.9. <ins> groupConnLimit Numeric (with special value "Unlimited") Unlimited This property controls the number of Connections that can be accepted from a peer as new members of the Connection's group.  Similar to SetNewConnectionLimit(), this limits the number of ConnectionReceived Events that will occur, but constrained to the group of the Connection associated with this property.  For a multi-streaming transport, this limits the number of allowed streams. 7.1.10. </ins> The following generic Connection Properties are read-only, i.e. they cannot be changed by an application.  <ins> 7.1.10.1. </ins> zeroRttMsgMaxLen before or during Connection establishment, see also msg- safelyreplayable.  It is given in Bytes.  <ins> 7.1.10.2. </ins> singularTransmissionMsgMaxLen Packet Size (MPS) as described in Datagram PLPMTUD I-D.ietf-tsvwg- datagram-plpmtud.  <ins> 7.1.10.3. </ins> sendMsgMaxLen This property represents the maximum Message size that an application can send.  <ins> 7.1.10.4. </ins> recvMsgMaxLen the remote peer.  This boolean becomes false when "Timeout for aborting Connection" (see conn-timeout) is used.  7.3. During the lifetime of a connection there are events that can occur


receive Events (see receive-events), the application can query information about the local and Remote Endpoint: <del> Message Contexts can also be used to send messages in reply to other messages, see send-replies for details. </del> 8.1.2. Although most applications communicate over a network using well- 8.2.2. <del> When a message is sent in response to a message received, the application can use the Message Context of the received Message to construct a Message Context for the reply. By using the "replyMessageContext", the transport system is informed that the message to be sent is a response and can map the response to the same underlying transport connection or the stream from which the request was received.  The concept of Message Contexts is described in msg-ctx. 8.2.3. </del> Like all Actions in this interface, the Send Action is asynchronous. There are several Events that can be delivered in response to Sending a Message.  Exactly one Event (Sent, Expired, or SendError) will be Action resulted in a particular Send Event.  The manner in which this correlation is indicated is implementation-specific. <del> 8.2.3.1. </del>  The Sent Event occurs when a previous Send Action has completed, i.e., when the data derived from the Message has been passed down or that always waits for the Sent Event before calling the next Send Action. <del> 8.2.3.2. </del>  The Expired Event occurs when a previous Send Action expired before completion; i.e. when the Message was not sent before its Lifetime Expired Event contains a reference to the Message to which it applies. <del> 8.2.3.3. </del>  A SendError occurs when a Message was not sent due to an error condition: an attempt to send a Message which is too large for the the Connection's transport properties.  The SendError contains a reference to the Message to which it applies. <del> 8.2.4. </del>  It is not always possible for an application to send all data associated with a Message in a single Send Action.  The Message data belonging to the same Message, and will constitute an in-order series until the endOfMessage is marked. <del> 8.2.5. </del>  To reduce the overhead of sending multiple small Messages on a Connection, the application could batch several Send Actions The semantics for starting and ending a batch can be implementation- specific, but need to allow multiple Send Actions to be enqueued. <del> 8.2.6. </del>  For application-layer protocols where the Connection initiator also sends the first message, the InitiateWithSend() action combines will not result in a SendError separate from the InitiateError signaling the failure of Connection establishment. <del> 8.2.7. </del>  The Transport Services interface provides two properties to allow a sender to signal the relative priority of data transmission: the

says: But it appears the Connection object is still required to call Send, so what value does this provide? I.e., how are you supposed to use replyMessageContext from the example?
I agree - it seems to me now that this really adds no value. What am I missing? I'm assigning NAME because he was among the first to propose this... maybe he can explain
Ping :)
Interim: We will remove all "reply/replies" from the API doc.

receive Events (see receive-events), the application can query information about the local and Remote Endpoint:  8.1.2. Although most applications communicate over a network using well- 8.2.2.  Like all Actions in this interface, the Send Action is asynchronous. There are several Events that can be delivered in response to Sending a Message.  Exactly one Event (Sent, Expired, or SendError) will be Action resulted in a particular Send Event.  The manner in which this correlation is indicated is implementation-specific.  <ins> 8.2.2.1. </ins> The Sent Event occurs when a previous Send Action has completed, i.e., when the data derived from the Message has been passed down or that always waits for the Sent Event before calling the next Send Action.  <ins> 8.2.2.2. </ins> The Expired Event occurs when a previous Send Action expired before completion; i.e. when the Message was not sent before its Lifetime Expired Event contains a reference to the Message to which it applies.  <ins> 8.2.2.3. </ins> A SendError occurs when a Message was not sent due to an error condition: an attempt to send a Message which is too large for the the Connection's transport properties.  The SendError contains a reference to the Message to which it applies.  <ins> 8.2.3. </ins> It is not always possible for an application to send all data associated with a Message in a single Send Action.  The Message data belonging to the same Message, and will constitute an in-order series until the endOfMessage is marked.  <ins> 8.2.4. </ins> To reduce the overhead of sending multiple small Messages on a Connection, the application could batch several Send Actions The semantics for starting and ending a batch can be implementation- specific, but need to allow multiple Send Actions to be enqueued.  <ins> 8.2.5. </ins> For application-layer protocols where the Connection initiator also sends the first message, the InitiateWithSend() action combines will not result in a SendError separate from the InitiateError signaling the failure of Connection establishment.  <ins> 8.2.6. </ins> The Transport Services interface provides two properties to allow a sender to signal the relative priority of data transmission: the


The transport services API uses the Local Endpoint and Remote Endpoint Objects to refer to the endpoints of a transport connection. <del> Actions on these Objects can be used to represent various different types of endpoint identifiers, such as IP addresses, DNS names, and interface names, as well as port numbers and service names. </del>  Specify a Remote Endpoint using a hostname and service name: Source-Specific Multicast requires setting both a Local and Remote Endpoint: <del> Implementations may also support additional endpoint representations and provide a single NewEndpoint() call that takes different endpoint representations. Multiple endpoint identifiers can be specified for each Local Endpoint and Remote Endpoint.  For example, a Local Endpoint could be configured with two interface names, or a Remote Endpoint could be specified via both IPv4 and IPv6 addresses.  These multiple identifiers refer to the same transport endpoint. The transport services API resolves names internally, when the Initiate(), Listen(), or Rendezvous() method is called to establish a Connection.  Privacy considerations for the timing of this resolution are given in privacy-security. The Resolve() action on Preconnection can be used by the application to force early binding when required, for example with some Network Address Translator (NAT) traversal protocols (see rendezvous). Specifying a multicast group address on the Local Endpoint will indicate to the transport system that the resulting connection will be used to receive multicast messages.  The Remote Endpoint can be used to filter by specific senders.  This will restrict the application to establishing the Preconnection by calling Listen(). The accepted Connections are receive-only. Similarly, specifying a multicast group address on the Remote Endpoint will indicate that the resulting connection will be used to send multicast messages. </del> 5.2. A Preconnection Object holds properties reflecting the application's

NAME does the update about transport aliasing help?
The call needs multiple local and remote candidate endpoints. This means should take lists of and objects (section 5) and there should be ways of adding/removing and objects from a Relates to
Pairs of? Local and remote endpoints probably need to be linked.
updates the description of to say: That's fine, but it prevents a single being used in when there are multiple candidates. For to work, we need to relax this restriction and allow multiple addresses of the same type to be added to an endpoint. NAME what's the rationale for the change in ?
I remember having multiple addresses on an endpoint would also benefit multicast.
NAME the explanation for how multicast is handled didn't change at all here, btw.
NAME I think it would make most sense to either: Use the alias approach, where one endpoint can have a list of aliases that are equivalent options, or Let the preconnection have multiple endpoint objects for rendezvous The definition of a single endpoint object is a lot easier to keep track of and understand if it is a single address or equivalent identifier.
sec 5.1 I found it odd that there didn't appear to be any sort of formal list of attributes of an endpoint, just some examples.
Should fix with
what happened if you add multiple addresses or interfaces to an endpoint: Does it overwrite the existing one or not?
I would say that it does not overwrite but simply add to a list of addresses. This is, among other things, because for a Listen() the remote endpoint can be used to filter incoming connections and I don't think it makes much sense to only be able to constrain it to a single address.
I agree with NAME – but we should really make this explicit
Discussion at interim: Clarification is needed. add() during preconnection will overwrite, and add() cannot be used in connection state. Also add a note in the text that e.g. specifying a specific IP address might restrict mobility or use of multiple paths and could cause the connection to fails when the IP address goes way rather than enabling some handover. Still open: Do we need a way to add of multiple addresses in the first place? This is used for filtering remote IP addresses for listener for multicast.
The current API text doesn't use "add", but rather "with...": It also implies that multiple is already allowed: How does that line up with the comment about , and having that replace?
As far as I can see, in the API draft we currently have add() for Properties and Security Parameters where each new add() overwrites the value for the old one. So if we change this to add(), probably IP addresses should work the same. But can't we just allow add() with a list of IP addresses instead of just with a single IP address?
Allow adding an alias endpoint to an endpoint Any one endpoint has at most one hostname Any one endpoint has at most one port/service (if you need more, add an alias) Any one endpoint has at most one address If you need multiple source-specific multicast filters, use multiple connection objects
From NAME The Preconnection Object must be specified with both a Local Endpoint and a Remote Endpoint, and also the transport properties and security parameters needed for Protocol Stack selection. To Rendezvous() we need multiple local and remote candidates. Should this be represented as either: Rendezvous() taking two lists of Preconnection objects; or as two Preconnection objects each with multiple addresses, ports, etc. I suggest option 1, since this makes it easier to resolve a Preconnection to multiple preconnections, for NAT binding discovery. Relates to but with also different types of endpoint.
I'm adding a point from NAME here (and closing a separate issue that he opened, because this tackles the same problem space): In the past, when I've designed transport abstraction APIs, I've always kept address family abstract, just as BSD sockets do. In this case, you've got WithIPv4Address and With IPv6Address as separate methods on the Endpoint type instead of just a single WithAddress method that takes an object of a type appropriate to the address family. Similarly, you've got WithPort as a first-class method instead of making it part of the Endpoint, as BSD sockets does with sockaddr_in. What if you want to support both TCP and QUIC, but the QUIC endpoint is on a different port? The notion of "port" is similar between the two, making the use of the same name appropriate, but it is only by convention that they often match: they are completely different spaces implemented in entirely separate codepaths in every network stack. ICMP doesn't even have a port: what if you wanted to use that (or some other port-less protocol that, for instance, multiplexes via IPv6 host ID) with this interface.

The transport services API uses the Local Endpoint and Remote Endpoint Objects to refer to the endpoints of a transport connection.  <ins> Endpoints can be created as either Remote or Local: A single Endpoint Object represents the identity of a network host. That endpoint can be more or less specific depending on which identifiers are set.  For example, an Endpoint that only specifies a hostname may in fact end up corresponding to several different IP addresses on different hosts. An Endpoint Object can be configured with the following identifiers: Hostname (string) Port (a 16-bit integer) or a Service (string) that maps to a port IP address (IPv4 or IPv6 address) Interface (string name) An Endpoint cannot have multiple identifiers of a same type set. That is, an endpoint cannot have two IP addresses specified.  Two separate IP addresses are represented as two Endpoint Objects.  If a Preconnection specifies a Remote Endpoint with a specific IP address set, it will only establish Connections to that IP address.  If, on the other hand, the Remote Endpoint specifies a hostname but no addresses, the Connection can perform name resolution and attempt using any address derived from the original hostname of the Remote Endpoint. The Transport Services API resolves names internally, when the Initiate(), Listen(), or Rendezvous() method is called to establish a Connection.  Privacy considerations for the timing of this resolution are given in privacy-security. The Resolve() action on a Preconnection can be used by the application to force early binding when required, for example with some Network Address Translator (NAT) traversal protocols (see rendezvous). 5.1.1. Specifying a multicast group address on a Local Endpoint will indicate to the transport system that the resulting connection will be used to receive multicast messages.  The Remote Endpoint can be used to filter incoming multicast from specific senders.  Such a Preconnection will only support calling Listen(), not Initiate(). The accepted Connections are receive-only. Similarly, specifying a multicast group address on the Remote Endpoint will indicate that the resulting connection will be used to send multicast messages. 5.1.2. An Endpoint can have an alternative definition when using different protocols.  For example, a server that supports both TLS/TCP and QUIC may be accessible on two different port numbers depending on which protocol is used. To support this, Endpoint Objects can specify "aliases".  An Endpoint can have multiple aliases set. In order to scope an alias to a specific transport protocol, an Endpoint can specify a protocol identifier.  These identifiers MUST only be set for aliases. The following example shows a case where "example.com" has a server running on port 443, with an alternate port of 8443 for QUIC. 5.1.3. The following examples of Endpoints show common usage patterns. </ins> Specify a Remote Endpoint using a hostname and service name: Source-Specific Multicast requires setting both a Local and Remote Endpoint:  5.2. A Preconnection Object holds properties reflecting the application's


5.2.2. <del> Protocol Properties represent the configuration of a transport protocol once it has been selected.  A transport protocol may not support all Protocol Properties, depending on the available transport features.  As with Transport Preferences (transport-prefs), Protocol Properties are specified on the Preconnection object, and are using during initiation of a Connection to help the system choose an appropriate transport.  The system will only actually set those protocol properties that are actually supported by the chosen transport protocol.  These properties all apply to Connections and Connection groups.  The default settings of these properties depends on the chosen protocol and on the system configuration. Set timeout for aborting Connection: This numeric property specifies how long to wait before aborting a Connection attempt. It is given in seconds. </del>  Set timeout to suggest to the peer: This numeric property specifies the timeout to propose to the peer.  It is given in before or during Connection establishment, see also send- idempotent.  It is given in Bytes.  5.2.3. Application Intents are a group of properties expressing what an

This addresses
Section 5.2.2. of the API should include the concept from the architecture of Specific Protocol Properties. I think expecting that all of these timeout/etc values should be the same no matter what protocol is selected is limiting, and a bit naive. I know as an application, for example, that I may need to do more keep alive activity to make NATs happy for UDP-based protocols than for TCP-based protocols (where are you, PLUS?!). Just a quick paragraph to indicate that the API can allow protocol-specific options to tune based on what is ultimately selected would be good.
let's race candidate authors for this paragraph ;) those who do not charter working groups for good ideas are doomed to forever reinvent them poorly.
Is 5.2.2 supposed to be the Specific Protocol Properties section? This section also seems to be a mix of things right now. I think this needs to be fixed as part of a bigger rework of section 5.2.
Agreed. Check out my pull request—I switch the text to talking about the architecture concepts of Generic Protocol Properties and Specific Protocol Properties.
That is better, but just a partial fix. I think we should get rid of the term Transport Preferences and the content of 5.2.1 and 5.2.2 needs to be reshuffled. Most of what is in 5.2.1 reads as protocol properties to me so I do not understand the current split.
That's fine with me. We could merge this PR in, and then as Brian does a pass, we can clean the rest up.
lgtm

5.2.2.  <ins> Protocol Properties represent the configuration that protocols should use once they have been selected.  Some properties apply generically across multiple transport protocols, in which case they may be used by the system to help select candidate protocols.  Other properties only apply to specific protocols.  As with Transport Preferences (transport-prefs), Protocol Properties are specified on the Preconnection object.  The default settings of these properties will vary based on the specific protocols being used and the system's configuration. Generic Protocol Properties include: Set timeout for aborting Connection establishment: This numeric property specifies how long to wait before aborting a Connection attempt.  It is given in seconds. </ins> Set timeout to suggest to the peer: This numeric property specifies the timeout to propose to the peer.  It is given in before or during Connection establishment, see also send- idempotent.  It is given in Bytes. <ins> In order to specify Specific Protocol Properties, the application can attach a set of options to the Preconnection object, associated with a specific protocol.  For example, the application could specify a set of TCP Options to use if and only if TCP is selected by the system, including options such as the Maximum Segment Size (MSS), and options around Acknowledgement Stretching.  Such properties should not be assumed to apply across different protocols, but must be possible to specify if required by the application. </ins> 5.2.3. Application Intents are a group of properties expressing what an


(connection-props), and the security parameters (see security- parameters): <del> The Local Endpoint MUST be specified if the Preconnection is used to Listen() for incoming Connections, but is OPTIONAL if it is used to Initiate() connections.  If no Local Endpoint is specified, the Transport System will assign an ephemeral local port to the Connection on the appropriate interface(s).  The Remote Endpoint MUST be specified if the Preconnection is used to Initiate() Connections, but is OPTIONAL if it is used to Listen() for incoming Connections. The Local Endpoint and the Remote Endpoint MUST both be specified if a peer-to-peer Rendezvous is to occur based on the Preconnection. </del>  Transport Properties MUST always be specified while security parameters are OPTIONAL.

The call needs multiple local and remote candidate endpoints. This means should take lists of and objects (section 5) and there should be ways of adding/removing and objects from a Relates to
Pairs of? Local and remote endpoints probably need to be linked.
updates the description of to say: That's fine, but it prevents a single being used in when there are multiple candidates. For to work, we need to relax this restriction and allow multiple addresses of the same type to be added to an endpoint. NAME what's the rationale for the change in ?
I remember having multiple addresses on an endpoint would also benefit multicast.
NAME the explanation for how multicast is handled didn't change at all here, btw.
NAME I think it would make most sense to either: Use the alias approach, where one endpoint can have a list of aliases that are equivalent options, or Let the preconnection have multiple endpoint objects for rendezvous The definition of a single endpoint object is a lot easier to keep track of and understand if it is a single address or equivalent identifier.

(connection-props), and the security parameters (see security- parameters):  <ins> At least one Local Endpoint MUST be specified if the Preconnection is used to Listen() for incoming Connections, but the list of Local Endpoints MAY be empty if the Preconnection is used to Initiate() connections.  If no Local Endpoint is specified, the Transport System will assign an ephemeral local port to the Connection on the appropriate interface(s).  At least one Remote Endpoint MUST be specified if the Preconnection is used to Initiate() Connections, but the list of Remote Endpoints MAY be empty if the Preconnection is used to Listen() for incoming Connections.  At least one Local Endpoint and one Remote Endpoint MUST be specified if a peer-to-peer Rendezvous is to occur based on the Preconnection. If more than one Local Endpoint is specified on a Preconnection, then all the Local Endpoints on the Preconnection MUST represent the same host.  For example, they might correspond to different interfaces on a multi-homed host, of they might correspond to local interfaces and a STUN server that can be resolved to a server reflexive address for a Preconnection used to make a peer-to-peer Rendezvous(). If more than one Remote Endpoint is specified on the Preconnection, then all the Remote Endpoints on the Preconnection SHOULD represent the same host.  For example, the Remote Endpoints might represent various network interfaces of a host, or a server reflexive address that can be used to reach a host, or a set of hosts that provide equivalent local balanced service. In most cases, it is expected that a single Remote Endpoint will be specified by name, and a later call to Initiate() on the Preconnection (see initiate) will internally resolve that name to a list of concrete endpoints.  Specifying multiple Remote Endpoints on a Preconnection allows applications to override this for more detailed control. </ins> Transport Properties MUST always be specified while security parameters are OPTIONAL.


Simultaneous peer-to-peer Connection establishment is supported by the Rendezvous() Action: <del> The Preconnection Object must be specified with both a Local Endpoint and a Remote Endpoint, and also the transport properties and security parameters needed for Protocol Stack selection. </del>  <del> The Rendezvous() Action causes the Preconnection to listen on the Local Endpoint for an incoming Connection from the Remote Endpoint, while also simultaneously trying to establish a Connection from the Local Endpoint to the Remote Endpoint. </del>  If there are multiple Local Endpoints or Remote Endpoints configured, <del> then initiating a rendezvous action will systematically probe the reachability of those endpoints following an approach such as that used in Interactive Connectivity Establishment (ICE) RFC5245. </del>  If the endpoints are suspected to be behind a NAT, Rendezvous() can <del> be initiated using Local and Remote Endpoints that support a method of discovering NAT bindings such as Session Traversal Utilities for NAT (STUN) RFC8489 or Traversal Using Relays around NAT (TURN) RFC5766.  In this case, the Local Endpoint will resolve to a mixture of local and server reflexive addresses.  The Resolve() action on the </del>  Preconnection can be used to discover these bindings: <del> The Resolve() call returns a list of Preconnection Objects, that represent the concrete addresses, local and server reflexive, on which a Rendezvous() for the Preconnection will listen for incoming Connections.  These resolved Preconnections will share all other Properties with the Preconnection from which they are derived, though some Properties may be made more-specific by the resolution process. </del>  An application that uses Rendezvous() to establish a peer-to-peer connection in the presence of NATs will configure the Preconnection <del> object with a Local Endpoint that supports NAT binding discovery.  It will then Resolve() on that endpoint, and pass the resulting list of candidate local addresses to the peer via a signalling protocol, for example as part of an ICE RFC5245 exchange within SIP RFC3261 or WebRTC RFC7478.  The peer will, via the same signalling channel, return the remote endpoint candidates.  These remote endpoint candidates are then configured on the Preconnection, allowing the Rendezvous() Action to be initiated. The Rendezvous() Action returns a Connection object.  Once Rendezvous() has been called, any changes to the Preconnection MUST NOT have any effect on the Connection.  However, the Preconnection can be reused, e.g., for Rendezvous of another Connection. </del>  The RendezvousDone<> Event occurs when a Connection is established with the Remote Endpoint.  For Connection-oriented transports, this Connectionless transports, it occurs when the first Message is received from the Remote Endpoint.  The resulting Connection is contained within the RendezvousDone<> Event, and is ready to use as <del> soon as it is passed to the application via the Event. </del>  An EstablishmentError occurs either when the Properties and Security Parameters of the Preconnection cannot be fulfilled for rendezvous or cannot be reconciled with the Local and/or Remote Endpoints, when the Local Endpoint or Remote Endpoint cannot be resolved, when no transport-layer connection can be established to the Remote Endpoint, <del> or when the application is prohibited from rendezvous by policy. When using some NAT traversal protocols, e.g., Interactive Connectivity Establishment (ICE) RFC5245, it is expected that the Local Endpoint will be configured with some method of discovering NAT bindings, e.g., a Session Traversal Utilities for NAT (STUN) server. In this case, the Local Endpoint may resolve to a mixture of local and server reflexive addresses.  The Resolve() action on the Preconnection can be used to discover these bindings: The Resolve() call returns a list of Preconnection Objects, that represent the concrete addresses, local and server reflexive, on which a Rendezvous() for the Preconnection will listen for incoming Connections.  These resolved Preconnections will share all other Properties with the Preconnection from which they are derived, though some Properties may be made more-specific by the resolution process. This list can be passed to a peer via a signalling protocol, such as SIP RFC3261 or WebRTC RFC7478, to configure the remote endpoint. </del>  6.4.

In §6.3 we have: This doesn't work, because takes only a single . The action on a should rather be on a or .

Simultaneous peer-to-peer Connection establishment is supported by the Rendezvous() Action:  <ins> A Preconnection Object used in a Rendezvous() MUST have both the Local Endpoint candidates and the Remote Endpoint candidates specified, along with the transport properties and security parameters needed for Protocol Stack selection, before the Rendezvous() Action is initiated. </ins>  <ins> The Rendezvous() Action listens on the Local Endpoint candidates for an incoming Connection from the Remote Endpoint candidates, while also simultaneously trying to establish a Connection from the Local Endpoint candidates to the Remote Endpoint candidates. </ins> If there are multiple Local Endpoints or Remote Endpoints configured,  <ins> then initiating a Rendezvous() action will systematically probe the reachability of those endpoint candidates following an approach such as that used in Interactive Connectivity Establishment (ICE) RFC5245. </ins> If the endpoints are suspected to be behind a NAT, Rendezvous() can  <ins> be initiated using Local Endpoints that support a method of discovering NAT bindings such as Session Traversal Utilities for NAT (STUN) RFC8489 or Traversal Using Relays around NAT (TURN) RFC5766. In this case, the Local Endpoint will resolve to a mixture of local and server reflexive addresses.  The Resolve() action on the </ins> Preconnection can be used to discover these bindings:  <ins> The Resolve() call returns lists of Local Endpoints and Remote Endpoints, that represent the concrete addresses, local and server reflexive, on which a Rendezvous() for the Preconnection will listen for incoming Connections, and to which it will attempt to establish connections. </ins> An application that uses Rendezvous() to establish a peer-to-peer connection in the presence of NATs will configure the Preconnection  <ins> object with at least one a Local Endpoint that supports NAT binding discovery.  It will then Resolve() the Preconnection, and pass the resulting list of Local Endpoint candidates to the peer via a signalling protocol, for example as part of an ICE RFC5245 exchange within SIP RFC3261 or WebRTC RFC7478.  The peer will then, via the same signalling channel, return the Remote Endpoint candidates.  The set of Remote Endpoint candidates are then configured onto the Preconnection: The Rendezvous() Action can be initiated once both the Local Endpoint candidates and the Remote Endpoint candidates retrieved from the peer via the signalling channel have been added to the Preconnection. If successful, the Rendezvous() Action returns a Connection object via a RendezvousDone<> Event: </ins> The RendezvousDone<> Event occurs when a Connection is established with the Remote Endpoint.  For Connection-oriented transports, this Connectionless transports, it occurs when the first Message is received from the Remote Endpoint.  The resulting Connection is contained within the RendezvousDone<> Event, and is ready to use as  <ins> soon as it is passed to the application via the Event.  Changes made to a Preconnection after Rendezvous() has been called do not have any effect on existing Connections. </ins> An EstablishmentError occurs either when the Properties and Security Parameters of the Preconnection cannot be fulfilled for rendezvous or cannot be reconciled with the Local and/or Remote Endpoints, when the Local Endpoint or Remote Endpoint cannot be resolved, when no transport-layer connection can be established to the Remote Endpoint,  <ins> or when the application is prohibited from rendezvous by policy: </ins> 6.4.


Services are: the Preconnection, the bundle of Properties that describes the <del> application constraints on the transport; </del>  the Connection, the basic object that represents a flow of data as Messages in either direction between the Local and Remote transfer.  During the process of establishment (conn-establish), the Connection will be unbound to a specific transport flow, since there may be multiple candidate Protocol Stacks being raced.  Once the <del> Connection is established, the object should be considered mapped to a specific Protocol Stack.  The notion of a Connection maps to many different protocols, depending on the Protocol Stack.  For example, the Connection may ultimately represent the interface into a TCP </del>  connection, a TLS session over TCP, a UDP flow with fully-specified local and remote endpoints, a DTLS session, a SCTP stream, a QUIC stream, or an HTTP/2 stream. 3. <del> During pre-establishment the application specifies the Endpoints to be used for communication as well as its preferences via Selection Properties and, if desired, also Connection Properties.  Generally, Connection Properties should be configured as early as possible, because they can serve as input to decisions that are made by the implementation (e.g., the Capacity Profile can guide usage of a protocol offering scavenger-type congestion control). </del>  The implementation stores these properties as a part of the Preconnection object for use during connection establishment.  For an order that results in usable leaf nodes whenever there are multiple branch types that could be used from a single node. <del> The order of operations for branching, where lower numbers are acted upon first, should be: </del>  Alternate Paths Derived Endpoints <del> Branching between paths is the first in the list because results across multiple interfaces are likely not related to one another: endpoint resolution may return different results, especially when using locally resolved host and service names, and which protocols are supported and preferred may differ across interfaces.  Thus, if multiple paths are attempted, the overall connection can be seen as a race between the available paths or interfaces. </del>  Protocol options are next checked in order.  Whether or not a set of protocol, or protocol-specific options, can successfully connect is the TCP handshake is complete, or it can wait for the TLS handshake to complete as well.  The benefit of declaring completion when the TCP handshake finishes, and thus stopping the race for other branches <del> of the tree, is that there will be less burden on the network from other connection attempts.  On the other hand, by waiting until the TLS handshake is complete, an implementation avoids the scenario in which a TCP handshake completes quickly, but TLS negotiation is either very slow or fails altogether in particular network conditions or to a particular endpoint.  To avoid the issue of TLS possibly failing, the implementation should not generate a Ready event for the Connection until TLS is established. </del>  If all of the leaf nodes fail to connect during racing, i.e. none of the configurations that satisfy all requirements given in the 4.6.1. Connected protocols such as TCP and TLS-over-TCP have a strong <del> mapping between the Local and Remote Endpoints (five-tuple) and their </del>  protocol connection state.  These map into Connection objects. Whenever a new inbound handshake is being started, the Listener should generate a new Connection object and pass it to the provide the same mechanisms that connected protocols do to offer Connection objects.  Implementations should wait for incoming packets for unconnected protocols on a listening port and should perform <del> five-tuple matching of packets to either existing Connection objects </del>  or the creation of new Connection objects.  On platforms with facilities to create a "virtual connection" for unconnected protocols implementations should use these mechanisms to minimise the handling 4.6.3. <del> Protocols that provide multiplexing of streams into a single five- </del>  tuple can listen both for entirely new connections (a new HTTP/2 stream on a new TCP connection, for example) and for new sub- connections (a new HTTP/2 stream on an existing connection).  If the bandwidth. An implementation should use this information, when possible, to <del> determine preference between candidate paths, endpoints, and protocol </del>  options.  Eligible options that historically had significantly better performance than others should be selected first when gathering candidates (see gathering) to ensure better performance for the

These are mostly wording changes for clarification. Feel free to cherry pick.
Can't find any problems here - this looks good.
This LGTM, many thanks!

Services are: the Preconnection, the bundle of Properties that describes the  <ins> application constraints on, and preferences for, the transport; </ins> the Connection, the basic object that represents a flow of data as Messages in either direction between the Local and Remote transfer.  During the process of establishment (conn-establish), the Connection will be unbound to a specific transport flow, since there may be multiple candidate Protocol Stacks being raced.  Once the  <ins> Connection is established, its interface maps actions and events to the details of the chosen Protocol Stack.  For example, the same Connection object may ultimately represent the interface into a TCP </ins> connection, a TLS session over TCP, a UDP flow with fully-specified local and remote endpoints, a DTLS session, a SCTP stream, a QUIC stream, or an HTTP/2 stream. 3.  <ins> During pre-establishment the application specifies one or more Endpoints to be used for communication as well as protocol preferences and constraints via Selection Properties and, if desired, also Connection Properties.  Generally, Connection Properties should be configured as early as possible, because they can serve as input to decisions that are made by the implementation (e.g., the Capacity Profile can guide usage of a protocol offering scavenger-type congestion control). </ins> The implementation stores these properties as a part of the Preconnection object for use during connection establishment.  For an order that results in usable leaf nodes whenever there are multiple branch types that could be used from a single node.  <ins> The order of operations for branching should be: </ins> Alternate Paths Derived Endpoints  <ins> where a lower number indicates higher precedence and therefore higher placement in the tree.  Branching between paths is the first in the list because results across multiple interfaces are likely not related to one another: endpoint resolution may return different results, especially when using locally resolved host and service names, and which protocols are supported and preferred may differ across interfaces.  Thus, if multiple paths are attempted, the overall connection can be seen as a race between the available paths or interfaces. </ins> Protocol options are next checked in order.  Whether or not a set of protocol, or protocol-specific options, can successfully connect is the TCP handshake is complete, or it can wait for the TLS handshake to complete as well.  The benefit of declaring completion when the TCP handshake finishes, and thus stopping the race for other branches  <ins> of the tree, is reduced burden on the network and remote endpoints from further connection attempts that are likely to be abandoned.  On the other hand, by waiting until the TLS handshake is complete, an implementation avoids the scenario in which a TCP handshake completes quickly, but TLS negotiation is either very slow or fails altogether in particular network conditions or to a particular endpoint.  To avoid the issue of TLS possibly failing, the implementation should not generate a Ready event for the Connection until TLS is established. </ins> If all of the leaf nodes fail to connect during racing, i.e. none of the configurations that satisfy all requirements given in the 4.6.1. Connected protocols such as TCP and TLS-over-TCP have a strong  <ins> mapping between the Local and Remote Endpoints (four-tuple) and their </ins> protocol connection state.  These map into Connection objects. Whenever a new inbound handshake is being started, the Listener should generate a new Connection object and pass it to the provide the same mechanisms that connected protocols do to offer Connection objects.  Implementations should wait for incoming packets for unconnected protocols on a listening port and should perform  <ins> four-tuple matching of packets to either existing Connection objects </ins> or the creation of new Connection objects.  On platforms with facilities to create a "virtual connection" for unconnected protocols implementations should use these mechanisms to minimise the handling 4.6.3.  <ins> Protocols that provide multiplexing of streams into a single four- </ins> tuple can listen both for entirely new connections (a new HTTP/2 stream on a new TCP connection, for example) and for new sub- connections (a new HTTP/2 stream on an existing connection).  If the bandwidth. An implementation should use this information, when possible, to  <ins> influence preference between candidate paths, endpoints, and protocol </ins> options.  Eligible options that historically had significantly better performance than others should be selected first when gathering candidates (see gathering) to ensure better performance for the


attempts in parallel, "unconnected" protocols such as raw UDP do not offer a way to validate the presence of a peer or the usability of a Connection without application feedback.  An implementation should <del> consider such a protocol stack to be established as soon as a local route to the peer endpoint is confirmed. </del>  However, if a peer is not reachable over the network using the unconnected protocol, or data cannot be exchanged for any other

My first try to make a PR from the web interface. Maybe this compiles without problems?
Aha, the error appears even when doing it over the web interface.
I think I am missing something ... how do endpoints know a route exists (is present)? My thinking from NEAT was that endpoints only knew this was established when there was some "confirmation" from the remote endpoint. Do you mean something else?
NAME this is for UDP, nothing is sent to the other end until the application sends data. it was the same in neat, our open call in neat just returned immediately for UDP.
True - for UDP, as you say, you basically know the Interface is up (and often not much more), but the words "established" sounds more like what happened when you get the first packet back... Maybe I could live with this, but it doesn't immediately inspire the right sense...
Yes, "connectivity is established" is not good at all, this is why I said the proposed update made it worse :) Or you mean that "local port reservations has been established" also triggers the wrong idea because of "established"? How about "... any necessary state like local port reservations is available/has been allocated." Or just remove that part all together.
In Sec 4.5 of taps-impl: "An implementation should consider such a protocol stack to be established as soon as a local route to the peer endpoint is confirmed." What does this mean for an unconnected protocol? That there is an entry in the route table, or that it's received a packet?
Good catch: This appears to be rough sentence. The term "confirmed" occurs only once, and a "local route" is something quite different to what is intended! We do talk about establishing connectivity with a remote endpoint... maybe that might work?

attempts in parallel, "unconnected" protocols such as raw UDP do not offer a way to validate the presence of a peer or the usability of a Connection without application feedback.  An implementation should  <ins> consider such a protocol stack to be established as soon as the Transport Services system has selected a path on which to send data. </ins> However, if a peer is not reachable over the network using the unconnected protocol, or data cannot be exchanged for any other


Before an implementation marks a Message Framer as ready, it can also dynamically add a protocol or framer above it in the stack.  This <del> allows protocols like STARTTLS, that need to add TLS conditionally, to modify the Protocol Stack based on a handshake result. </del>  6.2.

The implementation draft should explain that a framer can go into a passthrough/inactive mode once it has finished (like SOCKS, STARTTLS, CONNECT).

Before an implementation marks a Message Framer as ready, it can also dynamically add a protocol or framer above it in the stack.  This  <ins> allows protocols that need to add TLS conditionally, like STARTTLS RFC3207, to modify the Protocol Stack based on a handshake result. A Message Framer might also choose to go into a passthrough mode once an initial exchange or handshake has been completed, such as the STARTTLS case mentioned above.  This can also be useful for proxy protocols like SOCKS RFC1928 or HTTP CONNECT RFC7230.  In such cases, a Message Framer implementation can intercept sending and receiving of messages at first, but then indicate that no more processing is needed. </ins> 6.2.


path fails and fallback or re-establishment is supported in the Transport Services system.  The interface explicitly does not require the application to resolve names, though there is a tradeoff between early and late binding of addresses to names.  Early binding allows the API implementation to

If I understood this right: URL URL if this is even a reasonable source ... then what this attack does, is to take the TCP connection away underneath the application's feet. Then, an application may still expect parts of a message but they may in fact never arrive because the Connection is in fact gone. Doesn't this mean that this exploits a detachment between TCP and a protocol atop TCP, which doesn't inform the application of the arrival of a FIN? In this case, I don't understand the concern raised by NAME in : the delivery of "outstanding partial messages" means that the receiver has them in the buffer, and then a FIN arrives - upon reception of the FIN, these "outstanding partial messages" should be delivered. That seems right to me. I may easily be completely off track! But either way, NAME also noted in that the attack should be described, so I don't think that this PR satisfies the issue as it stands.
A contrived example of the problem is if you intend to execute "rm -rf /some/path" and it somehow gets truncated to "rm -rf /". Protocols need to be designed in such a way that they deal properly with partial messages. I think the proposed text is fine.
Aha! That's completely different than my reading of the Wikipedia page. Then that's fine, I also agree.
My 2c: You can always design bad apps: I don't think transports should be designed to do application data checks... applications should do that on the data they send.
The new text seems to say what it should, although I don't see what this is an "attack", it would happen naturally when communications breaks.
Maybe we should discuss this. I see the need for something here as twofold: Warn users that they should not ignore the API-enabled distinction between full and partial messages. Make sure implementors properly classify partial messages as partial, so truncated messages (whether resulting from an attack or not) are presented to the application in a way that it can respond appropriately. Specifically because TAPS provides message and layer abstractions (for security and framing), it's imperative that the implementor of each stage of the pipeline preserve the partial/full message distinction because unlike applications built on top of TCP sockets the application author may not have the ability to detect a partial message because windowing/framing at the lower layers aren't exposed to the application. Based on this conversation, it sounds like we do need the text to make this a bit clearer.
I think this is useful to keep in. Security considerations are always good to point out. Happy to take suggestions for clarity.
Under the doc says: Emphasis mine. This is a key enabler of truncation attacks, so the interface should only do this if the application is well aware of the implications of receiving partial messages and/or if the partial nature of the message is made clear to the application.
Perhaps would also need to spell-out what constitutes a truncation attack?
Should go into API security considerations to tell apps to be careful to not assume that when a connection closes that their received data was complete and/or well-formed.
This LGTMLGMT with NAME additions

path fails and fallback or re-establishment is supported in the Transport Services system. <ins> Applications should also take care to not assume that all data received using the Transport Services API is always complete or well- formed.  Specifically, messages that are received partially receive- partial could be a source of truncation attacks if applications do not distinguish between partial messages and complete messages. </ins> The interface explicitly does not require the application to resolve names, though there is a tradeoff between early and late binding of addresses to names.  Early binding allows the API implementation to