Draft: draft-ietf-taps-impl

Commentary: Trying to align more with  on the key terms 
 This is a request for a PR to align the API to this , and related Transport Services API : The application interface ( not the word interface where we can avoid this , to avoid confusion with network interfaces ) Transport Services implementation : The library / code below the API Transport Services system : The entire package of API and implementation Transport Services architecture . endpoint without /Local/ or /Remote/ never has a capital E
Paragraph (version A):
The Transport Services architecture I-D.ietf-taps-arch defines a
system that allows applications to use transport networking protocols
flexibly.  The interface such a system exposes to applications is
defined as the Transport Services API I-D.ietf-taps-interface.  This
API is designed to be generic across multiple transport protocols and
sets of protocols features.
Paragraph (version B):
The Transport Services architecture I-D.ietf-taps-arch defines a
system that allows applications to flexibly use transport networking
protocols.  The API that such a system exposes to applications is
defined as the Transport Services API I-D.ietf-taps-interface.  This
API is designed to be generic across multiple transport protocols and
sets of protocols features.
Paragraph (version A):
Once the 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 a single instance of
one transport protocol (e.g., a TCP 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).
The properties held by a Connection or Listener is independent of
other connections that are not part of the same Connection Group.
Paragraph (version B):
Once the Connection is established, Transport Services implementation
maps actions and events to the details of the chosen Protocol Stack.
For example, the same Connection object may ultimately represent a
single instance of one transport protocol (e.g., a TCP 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).  The properties held by a Connection or Listener is
independent of other connections that are not part of the same
Connection Group.
Paragraph (version A):
The primary goal of the Candidate Racing process is to successfully
negotiate a protocol stack to an endpoint over an interface--to
connect a single leaf node of the tree--with as little delay and as
few unnecessary connections attempts as possible.  Optimizing these
two factors improves the user experience, while minimizing network
load.
Paragraph (version B):
The primary goal of the Candidate Racing process is to successfully
negotiate a protocol stack to an endpoint over an interface to
connect a single leaf node of the tree with as little delay and as
few unnecessary connections attempts as possible.  Optimizing these
two factors improves the user experience, while minimizing network
load.
Paragraph (version A):
Multiplexing several Connections over a single underlying transport
connection requires that the Connections to be multiplexed belong to
the same Connection Group (as is indicated by the application using
the Clone call).  When the underlying transport connection supports
multi-streaming, the Transport System can map each Connection in the
Connection Group to a different stream.  Thus, when the Connections
that are offered to an application by the Transport System are
multiplexed, the Transport System may implement the establishment of
a new Connection by simply beginning to use a new stream of an
already established transport connection and there is no need for a
connection establishment procedure.  This, then, also means that
there may not be any "establishment" message (like a TCP SYN), but
the application can simply start sending or receiving.  Therefore,
when the Initiate action of a Transport System is called without
Messages being handed over, it cannot be guaranteed that the other
endpoint will have any way to know about this, and hence a passive
endpoint's ConnectionReceived event may not be called upon an active
endpoint's Inititate.  Instead, calling the ConnectionReceived event
may be delayed until the first Message arrives.
Paragraph (version B):
Multiplexing several Connections over a single underlying transport
connection requires that the Connections to be multiplexed belong to
the same Connection Group (as is indicated by the application using
the Clone call).  When the underlying transport connection supports
multi-streaming, the Transport Services System can map each
Connection in the Connection Group to a different stream.  Thus, when
the Connections that are offered to an application by the Transport
Services API are multiplexed, the Transport Services implementation
can establish a new Connection by simply beginning to use a new
stream of an already established transport Connection and there is no
need for a connection establishment procedure.  This, then, also
means that there may not be any "establishment" message (like a TCP
SYN), but the application can simply start sending or receiving.
Therefore, when the Initiate action of a Transport Services API is
called without Messages being handed over, it cannot be guaranteed
that the Remote Endpoint will have any way to know about this, and
hence a passive endpoint's ConnectionReceived event might not be
called until data is received.  Instead, calling the
ConnectionReceived event could be delayed until the first Message
arrives.
Paragraph (version A):
The application should be notified whenever a Message or partial
Message has been consumed by the Protocol Stack, or has failed to
send.  The time at which a Message is considered to have been
consumed by the Protocol Stack may vary depending on the protocol.
For example, for a basic datagram protocol like UDP, this may
correspond to the time when the packet is sent into the interface
driver.  For a protocol that buffers data in queues, like TCP, this
may correspond to when the data has entered the send buffer.  The
time at which a message has failed to send is after the Protocol
Stack or the Transport Services implementation itself has not
successfully sent the entire Message content or partial Message
content on any open candidate connection; this may depend on
protocol-specific timeouts.
Paragraph (version A):
Since sending a Message may involve a context switch between the
application and the transport system, sending patterns that involve
multiple small Messages can incur high overhead if each needs to be
enqueued separately.  To avoid this, the application can indicate a
batch of Send actions through the API.  When this is used, the
implementation can defer the processing of Messages until the batch
is complete.
Paragraph (version B):
The application should be notified whenever a Message or partial
Message has been consumed by the Protocol Stack, or has failed to
send.  The time at which a Message is considered to have been
consumed by the Protocol Stack may vary depending on the protocol.
For example, for a basic datagram protocol like UDP, this may
correspond to the time when the packet is sent into the interface
driver.  For a protocol that buffers data in queues, like TCP, this
may correspond to when the data has entered the send buffer.  The
time at which a message failed to send is when Transport Services
implementation (including the Protocol Stack) has not successfully
sent the entire Message content or partial Message content on any
open candidate connection; this can depend on protocol-specific
timeouts.
Paragraph (version B):
Since sending a Message may involve a context switch between the
application and the Transport Services system, sending patterns that
involve multiple small Messages can incur high overhead if each needs
to be enqueued separately.  To avoid this, the application can
indicate a batch of Send actions through the API.  When this is used,
the implementation can defer the processing of Messages until the
batch is complete.
Paragraph (version A):
Similar to sending, Receiving a Message is determined by the top-
level protocol in the established Protocol Stack.  The main
difference with Receiving is that the size and boundaries of the
Message are not known beforehand.  The application can communicate in
its Receive action the parameters for the Message, which can help the
implementation know how much data to deliver and when.  For example,
if the application only wants to receive a complete Message, the
implementation should wait until an entire Message (datagram, stream,
or frame) is read before delivering any Message content to the
application.  This requires the implementation to understand where
messages end, either via a supplied deframer or because the top-level
protocol in the established Protocol Stack preserves message
boundaries.  If the top-level protocol only supports a byte-stream
and no framers were supported, the application can control the flow
of received data by specifying the minimum number of bytes of Message
content it wants to receive at one time.
Paragraph (version A):
If a Connection finishes before a requested Receive action can be
satisfied, the implementation should deliver any partial Message
content outstanding, or if none is available, an indication that
there will be no more received Messages.
Paragraph (version B):
Similar to sending, Receiving a Message is determined by the top-
level protocol in the established Protocol Stack.  The main
difference with Receiving is that the size and boundaries of the
Message are not known beforehand.  The application can communicate in
its Receive action the parameters for the Message, which can help the
Transport Services implementation know how much data to deliver and
when.  For example, if the application only wants to receive a
complete Message, the implementation should wait until an entire
Message (datagram, stream, or frame) is read before delivering any
Message content to the application.  This requires the implementation
to understand where messages end, either via a supplied deframer or
because the top-level protocol in the established Protocol Stack
preserves message boundaries.  If the top-level protocol only
supports a byte-stream and no framers were supported, the application
can control the flow of received data by specifying the minimum
number of bytes of Message content it wants to receive at one time.
Paragraph (version B):
If a Connection finishes before a requested Receive action can be
satisfied, the Transport Services API should deliver any partial
Message content outstanding, or if none is available, an indication
that there will be no more received Messages.
Paragraph (version A):
Once the application has provided its 0-RTT data, an implementation
should keep a copy of this data and provide it to each new leaf node
that is started and for which a 0-RTT protocol is being used.
Paragraph (version B):
Once the application has provided its 0-RTT data, a Transport
Services implementation should keep a copy of this data and provide
it to each new leaf node that is started and for which a 0-RTT
protocol is being used.
Paragraph (version A):
While many protocols can be represented as Message Framers, for the
purposes of the Transport Services interface these are ways for
applications or application frameworks to define their own Message
parsing to be included within a Connection's Protocol Stack.  As an
example, TLS is exposed as a protocol natively supported by the
Transport Services interface, even though it could also serve the
purpose of framing data over TCP.
Paragraph (version B):
While many protocols can be represented as Message Framers, for the
purposes of the Transport Services API, these are ways for
applications or application frameworks to define their own Message
parsing to be included within a Connection's Protocol Stack.  As an
example, TLS is exposed as a protocol natively supported by the
Transport Services API, even though it could also serve the purpose
of framing data over TCP.
Paragraph (version A):
Common Message Framers can be provided by the Transport Services
implementation, but an implementation ought to allow custom Message
Framers to be defined by the application or some other piece of
software.  This section describes one possible interface for defining
Message Framers as an example.
Paragraph (version B):
Common Message Framers can be provided by a Transport Services
implementation, but an implementation ought to allow custom Message
Framers to be defined by the application or some other piece of
software.  This section describes one possible API for defining
Message Framers as an example.
Paragraph (version A):
A Message Framer is primarily defined by the code that handles events
for a framer implementation, specifically how it handles inbound and
outbound data parsing.  The function that implements custom framing
logic will be referred to as the "framer implementation", which may
be provided by the Transport Services implementation or the
application itself.  The Message Framer refers to the object or
function within the main Connection implementation that delivers
events to the custom framer implementation whenever data is ready to
be parsed or framed.
Paragraph (version B):
A Message Framer is primarily defined by the code that handles events
for a framer implementation, specifically how it handles inbound and
outbound data parsing.  The function that implements custom framing
logic will be referred to as the "framer implementation", which may
be provided by a Transport Services implementation or the application
itself.  The Message Framer refers to the object or function within
the main Connection implementation that delivers events to the custom
framer implementation whenever data is ready to be parsed or framed.
Paragraph (version A):
Should the framer implementation deem the candidate selected during
racing unsuitable it can signal this by failing the Connection prior
to marking it as ready.  If there are no other candidates available,
the Connection will fail.  Otherwise, the Connection will select a
different candidate and the Message Framer will generate a new
"Start" event.
Paragraph (version B):
Should the framer implementation deem the candidate selected during
racing unsuitable, it can signal this to the Transport Services API
by failing the Connection prior to marking it as ready.  If there are
no other candidates available, the Connection will fail.  Otherwise,
the Connection will select a different candidate and the Message
Framer will generate a new "Start" event.
Paragraph (version A):
Once a Connection is established, the Transport Services system
allows applications to interact with the Connection by modifying or
inspecting Connection Properties.  A Connection can also generate
events in the form of Soft Errors.
Paragraph (version A):
The set of Connection Properties that are supported for setting and
getting on a Connection are described in I-D.ietf-taps-interface.
For any properties that are generic, and thus could apply to all
protocols being used by a Connection, the Transport System should
store the properties in storage common to all protocols, and notify
all protocol instances in the Protocol Stack whenever the properties
have been modified by the application.  For protocol-specfic
properties, such as the User Timeout that applies to TCP, the
Transport System only needs to update the relevant protocol instance.
Paragraph (version B):
Once a Connection is established, the Transport Services API allows
applications to interact with the Connection by modifying or
inspecting Connection Properties.  A Connection can also generate
events in the form of Soft Errors.
Paragraph (version B):
The set of Connection Properties that are supported for setting and
getting on a Connection are described in I-D.ietf-taps-interface.
For any properties that are generic, and thus could apply to all
protocols being used by a Connection, the Transport Services
implementation should store the properties in storage common to all
protocols, and notify all protocol instances in the Protocol Stack
whenever the properties have been modified by the application.  For
protocol-specfic properties, such as the User Timeout that applies to
TCP, the Transport Services implementation only needs to update the
relevant protocol instance.
Paragraph (version A):
The Transport Services implementation should allow protocol instances
in the Protocol Stack to pass up arbitrary generic or protocol-
specific errors that can be delivered to the application as Soft
Errors.  These allow the application to be informed of ICMP errors,
and other similar events.
Paragraph (version B):
The Transport Services API should allow protocol instances in the
Protocol Stack to pass up arbitrary generic or protocol-specific
errors that can be delivered to the application as Soft Errors.
These allow the application to be informed of ICMP errors, and other
similar events.
Paragraph (version A):
When a path change occurs, e.g., when the IP address of an interface
changes or a new interface becomes available, the Transport Services
implementation is responsible for notifying the Protocol Instance of
the change.  The path change may interrupt connectivity on a path for
an active connection or provide an opportunity for a transport that
supports multipath or migration to adapt to the new paths.  Note
that, from the Transport Services API point of view, migration is
considered a part of multipath connectivity; it is just a limiting
policy on multipath usage.  If the "multipath" Selection Property is
set to "Disabled", migration is disallowed.
Paragraph (version B):
When a path change occurs, e.g., when the IP address of an interface
changes or a new interface becomes available, the Transport Services
implementation is responsible for notifying the Protocol Instance of
the change.  The path change may interrupt connectivity on a path for
an active connection or provide an opportunity for a transport that
supports multipath or migration to adapt to the new paths.  Note
that, in the model of the Transport Services API, migration is
considered a part of multipath connectivity; it is just a limiting
policy on multipath usage.  If the "multipath" Selection Property is
set to "Disabled", migration is disallowed.
Paragraph (version A):
Implementing a protocol independent transport system means that the
exposed semantics must be the strictest subset of the semantics of
all supported protocols.  Hence, as is common with all reliable
transport protocols, after a Close action, the application can expect
to have its reliability requirements honored regarding the data it
has given to the Transport System, but it cannot expect to be able to
read any more data after calling Close.
Paragraph (version A):
Abort differs from Close only in that no guarantees are given
regarding data that the application has handed over to the Transport
System before calling Abort.
Paragraph (version A):
As explained in establish-mux, when a new stream is multiplexed on an
already existing connection of a Transport Protocol Instance, there
is no need for a connection establishment procedure.  Because the
Connections that are offered by the Transport System can be
implemented as streams that are multiplexed on a transport protocol's
connection, it can therefore not be guaranteed that one Endpoint's
Initiate action provokes a ConnectionReceived event at its peer.
Paragraph (version B):
Implementing a protocol independent transport system means that the
exposed semantics must be the strictest subset of the semantics of
all supported protocols.  Hence, as is common with all reliable
transport protocols, after a Close action, the application can expect
to have its reliability requirements honored regarding the data
provided to the Transport Services API, but it cannot expect to be
able to read any more data after calling Close.
Paragraph (version B):
Abort differs from Close only in that no guarantees are given
regarding any data that the application sent to the Transport
Services API before calling Abort.
Paragraph (version B):
As explained in establish-mux, when a new stream is multiplexed on an
already existing connection of a Transport Protocol Instance, there
is no need for a connection establishment procedure.  Because the
Connections that are offered by a Transport Services implementation
can be implemented as streams that are multiplexed on a transport
protocol's connection, it can therefore not be guaranteed an Initiate
action from one endpoint provokes a ConnectionReceived event at its
peer.
Paragraph (version A):
Cached state may be associated with different Endpoints for the same
Connection, depending on the protocol generating the cached content.
For example, session tickets for TLS are associated with specific
endpoints, and thus should be cached based on a Connection's hostname
Endpoint (if applicable).  On the other hand, performance
characteristics of a path are more likely tied to the IP address and
subnet being used.
Paragraph (version B):
Cached state may be associated with different endpoints for the same
Connection, depending on the protocol generating the cached content.
For example, session tickets for TLS are associated with specific
endpoints, and thus should be cached based on a Connection's hostname
endpoint (if applicable).  However, performance characteristics of a
path are more likely tied to the IP address and subnet being used.
Paragraph (version A):
Applications can request that a Connection Group maintain a separate
cache for protocol state.  Connections in the group will not use
cached state from connections outside the group, and connections
outside the group will not use state cached from connections inside
the group.  This may be necessary, for example, if application-layer
identifiers rotate and clients wish to avoid linkability via
trackable TLS tickets or TFO cookies.
Paragraph (version B):
Applications can use the Transport Services API to request that a
Connection Group maintain a separate cache for protocol state.
Connections in the group will not use cached state from connections
outside the group, and connections outside the group will not use
state cached from connections inside the group.  This may be
necessary, for example, if application-layer identifiers rotate and
clients wish to avoid linkability via trackable TLS tickets or TFO
cookies.
Paragraph (version A):
Each protocol that can run as part of a Transport Services
implementation should have a well-defined API mapping.  API mappings
for a protocol apply most to Connections in which the given protocol
is the "top" of the Protocol Stack.  For example, the mapping of the
"Send" function for TCP applies to Connections in which the
application directly sends over TCP.
Paragraph (version B):
Each protocol that is supported by a Transport Services
implementation should have a well-defined API mapping.  API mappings
for a protocol are important for Connections in which a given
protocol is the "top" of the Protocol Stack.  For example, the
mapping of the "Send" function for TCP applies to Connections in
which the application directly sends over TCP.
Paragraph (version A):
Calling "Clone" on a TCP Connection creates a new Connection with
equivalent parameters.  These Connections, and Connections
generated via later calls to "Clone" on one of them, form a
Connection Group.  To realize entanglement for these Connections,
with the exception of "Connection Priority", changing a Connection
Property on one of them must affect the Connection Properties of
the others too.  No guarantees of honoring the Connection Property
"Connection Priority" are given, and thus it is safe for an
implementation of a transport system to ignore this property.
When it is reasonable to assume that Connections traverse the same
path (e.g., when they share the same encapsulation), support for
it can also experimentally be implemented using a congestion
control coupling mechanism (see for example TCP-COUPLING or
RFC3124).
Paragraph (version B):
Calling "Clone" on a TCP Connection creates a new Connection with
equivalent parameters.  These Connections, and Connections
generated via later calls to "Clone" on an Establied Connection,
form a Connection Group.  To realize entanglement for these
Connections, with the exception of "Connection Priority", changing
a Connection Property on one of them must affect the Connection
Properties of the others too.  No guarantees of honoring the
Connection Property "Connection Priority" are given, and thus it
is safe for an implementation of a transport system to ignore this
property.  When it is reasonable to assume that Connections
traverse the same path (e.g., when they share the same
encapsulation), support for it can also experimentally be
implemented using a congestion control coupling mechanism (see for
example TCP-COUPLING or RFC3124).
Paragraph (version A):
API mappings for MPTCP are identical to TCP.  MPTCP adds support for
multipath properties, such as "Multipath Transport" and "Policy for
using Multipath Transports".
Paragraph (version B):
the Transport Services API mappings for MPTCP are identical to TCP.
MPTCP adds support for multipath properties, such as "Multipath
Transport" and "Policy for using Multipath Transports".
Paragraph (version A):
API mappings for UDP-Lite are identical to UDP.  Properties that
require checksum coverage are not supported by UDP-Lite, such as
"Corruption Protection Length", "Full Checksum Coverage on Sending",
"Required Minimum Corruption Protection Coverage for Receiving", and
"Full Checksum Coverage on Receiving".
Paragraph (version B):
The Transport Services API mappings for UDP-Lite are identical to
UDP.  Properties that require checksum coverage are not supported by
UDP-Lite, such as "Corruption Protection Length", "Full Checksum
Coverage on Sending", "Required Minimum Corruption Protection
Coverage for Receiving", and "Full Checksum Coverage on Receiving".
Paragraph (version A):
There are cases where it is required to open multiple connections for
the same address(es).  For example, one Connection might be opened
for a multicast group to for a multicast control bus, and another
application later opens a separate Connection to the same group to
send signals to and/or receive signals from the common bus.  In such
cases, the interface needs to explicitly enable re-use of the same
set of addresses (equivalent to setting SO_REUSEADDR in the socket
API).
Paragraph (version B):
There are cases where it is required to open multiple connections for
the same address(es).  For example, one Connection might be opened
for a multicast group to for a multicast control bus, and another
application later opens a separate Connection to the same group to
send signals to and/or receive signals from the common bus.  In such
cases, the Transport Services system needs to explicitly enable re-
use of the same set of addresses (equivalent to setting SO_REUSEADDR
in the socket API).
Paragraph (version A):
Stream mapping requires an association to already be in place between
the client and the server, and it requires the server to understand
that a new incoming stream should be represented as a new Connection
Object by the Transport Services system.  A new SCTP stream is
created by sending an SCTP message with a new stream id.  Thus, to
implement stream mapping, the Transport Services system MUST provide
a newly created Connection Object to the application upon the
reception of such a message.  The necessary semantics to implement a
Transport Services system's Close and Abort primitives are provided
by the stream reconfiguration (reset) procedure described in RFC6525.
This also allows to re-use a stream id after resetting ("closing")
the stream.  To implement this functionality, SCTP stream
reconfiguration RFC6525 MUST be supported by both the client and the
server side.
Paragraph (version B):
Stream mapping requires an association to already be in place between
the client and the server, and it requires the server to understand
that a new incoming stream should be represented as a new Connection
Object by the Transport Services system.  A new SCTP stream is
created by sending an SCTP message with a new stream id.  Thus, to
implement stream mapping, the Transport Services API MUST provide a
newly created Connection Object to the application upon the reception
of such a message.  The necessary semantics to implement a Transport
Services system Close and Abort primitives are provided by the stream
reconfiguration (reset) procedure described in RFC6525.  This also
allows to re-use a stream id after resetting ("closing") the stream.
To implement this functionality, SCTP stream reconfiguration RFC6525
MUST be supported by both the client and the server side.