Subject: [core] Ben Campbell's Discuss on draft-ietf-core-coap-tcp-tls-08: (with DISCUSS and COMMENT)

From: Ben Campbell <[email-masked]>
Date: Tue, 09 May 2017 19:25:55 -0700

Ben Campbell has entered the following ballot position for
draft-ietf-core-coap-tcp-tls-08: Discuss

When responding, please keep the subject line intact and reply to all
email addresses included in the To and CC lines. (Feel free to cut this
introductory paragraph, however.)

Please refer to https://www.ietf.org/iesg/statement/discuss-criteria.html
for more information about IESG DISCUSS and COMMENT positions.

The document, along with other ballot positions, can be found here:
https://datatracker.ietf.org/doc/draft-ietf-core-coap-tcp-tls/

----------------------------------------------------------------------
DISCUSS:
----------------------------------------------------------------------

1) This draft removes the reliability and ordering features COAP when
used
over reliable transports, under the assumption that the transport will
provide. But the draft also includes the assumption that COAP proxies
exist.
This has the potential for creating a problem, since the transport can
only
provide guaranty reliable delivery and ordering to the next hop. Once
you
have a proxy in play, you loose that guaranty end to end.

This is further complicated because this draft contemplates
cross-transport
proxies, where one side may be over WebSocket (and I assume might be
over
TCP) and the other side over UDP. If the client sends via TCP but a
proxy
changes it to UDP, the client has no way to specify the reliability
properties to be used on the UDP connection. If one imagines a client
that uses
UDP to a forward proxy, which speaks TCP to a reverse-proxy, which then
switches back to UDP, any reliability properties specified by the client
will get
lost.

Also, a proxy can potentially reorder messages, even if it uses TCP on
both
sides. If one leaves ordering to the transport, then one needs to add
rules
about proxies maintaining that order.

2) It seems problematic to encode the transport choice in the URI
scheme.
Since the draft specifies that each scheme. Section 7 says "They are
hosted
in distinct namespaces because each URI scheme implies a distinct
origin
server." IIUC, this means any given resource can only be reached over a
specific transport. That seems to break the idea of cross-transport
proxies
as discussed in section 7.

It also does not seem to fit with a primary motivation for this draft.
That
is, one might want to use TCP because of local NAT/FW issues. But if
there is
a resource with a "coap" scheme, I cannot switch to TCP when I'm behind
a
problematic middlebox, and have an expectation of reaching the same
resource.

----------------------------------------------------------------------
COMMENT:
----------------------------------------------------------------------

Subtantive:

3.2: I agree with Adam that this length scheme seems very complex for
the
return

3.3: Since the initiator can start sending messages before receiving a
CSM
from the responder, how long should the initiator wait for a CSM before
bailing?

3.4: Can you offer any guidance about how often to send keep-alives? I
note
that these keepalives are not necessarily bi-directional. Aren't there
some
NAT/FW cases where bi-directional traffic is needed to keep bindings
from
timing out?

This and other places explicitly mention that in-flight messages may be
lost
when the transport is closed or reset. This creates uncertainty about
whether
such messages have been processed or not. Is that really okay?

4: After the discussion resulting from Mark's Art-Art review, I expected
to
see more emphasis about WebSocket being intended for browser-based
clients.
There's a couple of in-passing mentions of browser-clients buried in
the
text; I would have expected something more up front.

4.2: Is it really worth making the framing code behave differently for
WebSocket than for TCP?

5.3: Do I understand correctly that once an option is established, it
cannot
be removed unless replaced? (Short of tearing down the connection and
starting over, anyway.)

7.2: The text mentions 443 as a default port, but really seems to make
5684
the default. If 443 is really a default, then this needs  discussion
about
why and why it's okay to squat on HTTPS.

The text about whether ALPN is required is confusing. Why not just
require
ALPN and move one, rather than special casing it by port choice? (There
seems
to be some circular logic about requiring 5685 to support clients that
don't
do ALPN, then saying clients MUST do ALPN unless they are using port
5685.)

7.3: I agree with Adam's DISCUSS comment. And even if people decide that
the
well-known bit can be specified in CORE, I think it does future users of
a
well-known URIs for ws a disservice to make them dig through this spec
to
find the update to 6455.  It would be better to pull that into a
separate
draft. That's also a material addition post IETF last call, so we should
consider
repeating the LC.

10.2: Is the registration policy "analogous to" that of [RFC7252] S12.2,
or
"identical to" it. If the answer is not "identical", then the policy
should be detailed here.

Editorial:

Figures 7 and 8: "Payload (if any)" - Can we assume that if one uses
either
extended length format, one has a payload?

3.3: Is the guidance about what errors to return if you don't implement
a
server any different here than for UDP?

4.3 and 4.4 seem to primarily repeat details that are the same for WS as
for
TCP, even though the introduction to the WS part says that it won't do
that
:-)

5.3: "One CSM MUST be sent by both endpoints...": s/both/each

7.6: The "updates" in this section are confusing. I understand this to
mean
that the procedures for TCP and WS are identical to those for UDP except
for
the mentioned steps. But the language of the form of "This step from
[RFC7252] is updated to:" makes it sound like this intends to actually
change
the language in 7252 to this new language. If the latter, then that
effectively removes UDP support from 7252 as updated.

This could easily be fixed by changing that to something to the effect
of
"When using TCP, this step changes to ..."

Appendix A: Why is this an appendix? Updates to a standards track RFC
seem to
warrant a more prominent position in the draft.

---

From: Carsten Bormann <[email-masked]>
Date: Wed, 10 May 2017 21:38:28 +0200

Hi Ben,

now for the other parts.

> provide.

Yes.

> But the draft also includes the assumption that COAP proxies
> exist.

This is not a new situation; we have had UDP-to-UDP proxies before (as well as cross-protocol proxies).

> have a proxy in play, you loose that guaranty end to end.

There is no guarantee in any of the transports.  End-to-end semantics require end-to-end support.

> switches back to UDP, any reliability properties specified by the client

That has been true for UDP-to-UDP proxies, too.
(I wrote a little bit about that in https://mailarchive.ietf.org/arch/msg/core/Gpk8y4J78Pm7C8lKqMtxWdrzce0 .)

> about proxies maintaining that order.

There are no new rules here — everything a UDP-to-UDP CoAP proxy needed to do also needs to be done if one side is TCP.

> 2) […]

(See previous message.)

(1) This is a copy of what CoAP does for option lengths
(2) The WG originally wanted to use something simpler, but got pulled over to the current scheme by OCF.

> from the responder, how long should the initiator wait for a CSM before

I don’t think there should be a recommendation here.
I’d say: Wait for the CSM if you can afford it; start sending if you can’t.

> NAT/FW cases where bi-directional traffic is needed to keep bindings

Reference [HomeGateway] may be useful here.  Adaptive algorithms are probably going to have the best performance here.

> such messages have been processed or not. Is that really okay?

It is not ideal, in particular for methods that are not idempotent (e.g., POST).
The Web has had that problem for a long time now and has evolved ways to deal with the uncertainty.
But it does require attention from application programmers.

> text; I would have expected something more up front.

The introduction currently motivates the WebSockets part with:

   CoAP applications running inside a web browser without access to
   connectivity other than HTTP and the WebSocket protocol [RFC6455] may
   cross-proxy their CoAP requests via HTTP to a HTTP-to-CoAP cross-
   proxy or transport them via the the WebSocket protocol, which
   provides two-way communication between a WebSocket client and a
   WebSocket server after upgrading an HTTP/1.1 [RFC7230] connection.

How could we emphasize browsers even more?

> 4.2: Is it really worth making the framing code behave differently for

WebSockets already has framing, which we use (and thus do not populate the length field).
TCP (TLS) doesn’t, so we do need the length.  
Since the implementations are likely to be completely different anyway, I don’t see a big problem in that minor difference.

> be removed unless replaced? (Short of tearing down the connection and

Some CSM capability indicating options are that way, yes (e.g., the Block capability).
Why would such a capability go away during a connection?

> why and why it's okay to squat on HTTPS.

Well, 443 is the general port for ALPN.
5684 is for the case without ALPN.
But see also https://github.com/core-wg/coap-tcp-tls/issues/155

> do ALPN, then saying clients MUST do ALPN unless they are using port

I believe the text is consistent here. It just may be more complicated than needed, depending on how much you believe ALPN is already ubiquitous.  See https://github.com/core-wg/coap-tcp-tls/issues/155 for the question we have taken home as homework.

> draft. That's also a material addition post IETF last call, so we should

Of course, we will follow the wisdom of the IESG of how to handle this.

> "identical to" it. If the answer is not "identical", then the policy

It is analogous, because the structure of the subregistry is slightly different (additional column).
We can add a sentence that the value of the additional column does not influence the choice of the policy.

> extended length format, one has a payload?

In practice yes, but the options could be verrrrry long.
The figures try to show the similarity of the subformats, not the differences...

> server any different here than for UDP?

A UDP server can send a reset.  The equivalent here of closing down the TCP connection is unhealthy for the other direction, that’s why it is good to have some response.

> TCP, even though the introduction to the WS part says that it won't do

Right.  Diminishing returns, though.

> 5.3: "One CSM MUST be sent by both endpoints...": s/both/each

Good point.

> effectively removes UDP support from 7252 as updated.

OK, “update” is not the right word them.

> "When using TCP, this step changes to …"

Good point.
> warrant a more prominent position in the draft.

It was smeared all over the document, and then we collected it in an appendix.
I don’t think anyone would have a strong opposition against making it a mainline section.
Should we?

I have collected the editorial issues into https://github.com/core-wg/coap-tcp-tls/issues/158 (at least the ones where I know what we need to do or what needs to be discussed).

Grüße, Carsten

---

From: Ben Campbell <[email-masked]>
Date: Wed, 10 May 2017 21:07:10 -0500

> On May 10, 2017, at 2:38 PM, Carsten Bormann <[email-masked]> wrote:
> 
> Hi Ben,
> 
> now for the other parts.
> 

Sure, but I guess I was more talking about proxies that translate between two transports, which of course could not exist until we started talking about additional transports.

> (I wrote a little bit about that in https://mailarchive.ietf.org/arch/msg/core/Gpk8y4J78Pm7C8lKqMtxWdrzce0 .)

With UDP, it was at least possible for a proxy to preserve the reliability type. A proxy could strip that, but it didn’t _have_ to strip that. In the scenarios I mention, it’s not possible for the proxy to preserve the reliability type, because it never sees it. 

> There are no new rules here — everything a UDP-to-UDP CoAP proxy needed to do also needs to be done if one side is TCP.

So maybe I misunderstand something here, at least about ordering in COAP. Doesn’t COAP/UDP have an application layer order-preservation mechanism? Is it not at least _possible_ for a UDP-UDP proxy to preserve that mechanism across transport instances?

---

From: Carsten Bormann <[email-masked]>
Date: Thu, 11 May 2017 15:55:26 +0200

> Sure, but I guess I was more talking about proxies that translate between two transports, which of course could not exist until we started talking about additional transports.

The cognitive dissonance here comes from the fact that there is no way to specify a reliability level on a TCP hop, and some people have assumed that specifying a reliability level on a UDP hop somehow binds a proxy to use the same level on the next hop.  But that assumption is not justified.

> With UDP, it was at least possible for a proxy to preserve the reliability type.

Yes.  The UDP reliability type is moderately useful as a hint.  If we want to add a hinting mechanism to TCP, we can put in an option — this could then also be defined to give more useful hints (and then would be useful for UDP, too).

> A proxy could strip that, but it didn’t _have_ to strip that. In the scenarios I mention, it’s not possible for the proxy to preserve the reliability type, because it never sees it. 

Well, TCP is reliable, so it is possible to preserve that reliability on the next hop.
What you can’t do today is proxy from unreliable UDP to TCP and mark the TCP transaction as unreliable because you expect the next proxy to follow that mark in selecting its reliability type on the next UDP hop.  If that scenario sounds contrived, well, it is.

> So maybe I misunderstand something here, at least about ordering in COAP. Doesn’t COAP/UDP have an application layer order-preservation mechanism?

Yes, but only for notification.  Complete request/response exchanges can use causal ordering at the application layer (send the next request only after receiving the response for the previous request), so, like HTTP, they don’t have any ordering at the transfer protocol level.
For ordering notifications, Observe (RFC7641) has a simple sequence numbering scheme.  We don’t need that on TCP, as all notifications from a single observation interest share a TCP connection and are thus already ordered by that connection.

> Is it not at least _possible_ for a UDP-UDP proxy to preserve that mechanism across transport instances?

For observe, a simple UDP-UDP proxy could hand through the observe sequence number if it uses observe on both ends.
This is a bit tenuous, as proxying adds jitter and the temporal range covered by the sequence number is limited, but the configurations where this matters are probably pathological.
A UDP-UDP proxy needs to generate its own sequence number if it uses polling on the origin server side.  It needs to discard out-of-order notifications if it is a caching proxy.  I would prefer to write up all these implementation strategies in the lwig-coap draft, which has a whole section on CoAP on various transports.

[snip]

Grüße, Carsten