Discussion:
[core] Ben Campbell's Discuss on draft-ietf-core-coap-tcp-tls-08: (with DISCUSS and COMMENT)
Ben Campbell
2017-05-10 02:25:55 UTC
Permalink
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.
Ben Campbell
2017-05-10 02:27:01 UTC
Permalink
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.
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.
Carsten Bormann
2017-05-10 08:20:45 UTC
Permalink
Hi Ben,

thank your for your review.
Post by Ben Campbell
2) It seems problematic to encode the transport choice in the URI
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.
I would rephrase the issue as:
URIs don’t have a good place to put in transport hints.

(The definition of a transport hint in a URI would be information that lets me set up specific transports without creating a separate resource each time the values of that transport hint differ.)

Note that the main use case for the document at hand is one where the client may not be able to reach the server on the “main” transport (CoAP over UDP), so negotiation/upgrade(*) mechanisms are not solving the problem.

The solutions that people are talking about in our domain are about carrying transport alternatives around together.
E.g., see draft-silverajan-core-coap-protocol-negotiation-05.txt, which provides a way to find out about links from a set of links (the resource directory) while specifying a transport type. [It may be instructive to go through previous versions of this document just to see what we also have tried to do.]

What we have right now in draft-ietf-core-coap-tcp-tls is what we think is the least ugly way to solve the problem.
The WG is well aware about its problems.
We’d rather have a mechanism like transport hints, but we did not find a solution that would not need to update the web architecture.

Grüße, Carsten

(*) This is not an “upgrade” in the sense of going to a higher version of something in any case; it is just an alternative transport.
Ben Campbell
2017-05-10 16:56:25 UTC
Permalink
Post by Carsten Bormann
Hi Ben,
thank your for your review.
Post by Ben Campbell
2) It seems problematic to encode the transport choice in the URI
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.
URIs don’t have a good place to put in transport hints.
(The definition of a transport hint in a URI would be information that lets me set up specific transports without creating a separate resource each time the values of that transport hint differ.)
Note that the main use case for the document at hand is one where the client may not be able to reach the server on the “main” transport (CoAP over UDP), so negotiation/upgrade(*) mechanisms are not solving the problem.
That’s exactly what I mean by “a primary motivation”. As defined, the name of a resource declares the transport. So if I have a “coap” scheme resource that I cannot reach over UDP, I cannot simply switch to TCP and reach that same resource, even if the server supports both UDP and TCP. I suppose the server could treat the two resources as aliases, but the client cannot know that without some out-of-band agreement. (but see next comment)

So is it expected that people have to decide in advance which transport will be use for any given resource? The middlebox-traversal use case would seem to favor approaches where the client gets to decide what transport to use on the fly.
Post by Carsten Bormann
The solutions that people are talking about in our domain are about carrying transport alternatives around together.
E.g., see draft-silverajan-core-coap-protocol-negotiation-05.txt, which provides a way to find out about links from a set of links (the resource directory) while specifying a transport type. [It may be instructive to go through previous versions of this document just to see what we also have tried to do.]
So from an admittedly very quick scan, am I correct to assume that the directory described in that draft could be as “out-of-band” mechanism to declare resource aliases as I mentioned above? So why not use that sort of mechanism to advertise the available transports for an authority, and at least allow the transport selection to be completely decoupled from the scheme?

If people really want to bind transport selection to the resource name, then some such mechanism seems to be a requirement to make the solution in this draft fit for purpose. But the transport-negotiation draft is not yet adopted by CORE. Does it make sense to publish this before that is well on it’s way to ready?
Post by Carsten Bormann
What we have right now in draft-ietf-core-coap-tcp-tls is what we think is the least ugly way to solve the problem.
The WG is well aware about its problems.
We’d rather have a mechanism like transport hints, but we did not find a solution that would not need to update the web architecture.
At least some other protocols do this with DNS NAPTR records. I realize that may not be realistic for constrained devices (and I gather the protocol-negotiation draft attacks that same problem.) SIP, for example, can specify the transport with a URI parameter, which allows a URI to either specify a transport or to be transport-independent (by leaving off the parameter.)

Thanks!

Ben.
Carsten Bormann
2017-05-10 18:54:13 UTC
Permalink
Post by Ben Campbell
Post by Carsten Bormann
Hi Ben,
thank your for your review.
Post by Ben Campbell
2) It seems problematic to encode the transport choice in the URI
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.
URIs don’t have a good place to put in transport hints.
(The definition of a transport hint in a URI would be information that lets me set up specific transports without creating a separate resource each time the values of that transport hint differ.)
Note that the main use case for the document at hand is one where the client may not be able to reach the server on the “main” transport (CoAP over UDP), so negotiation/upgrade(*) mechanisms are not solving the problem.
That’s exactly what I mean by “a primary motivation”. As defined, the name of a resource declares the transport. So if I have a “coap” scheme resource that I cannot reach over UDP, I cannot simply switch to TCP and reach that same resource, even if the server supports both UDP and TCP. I suppose the server could treat the two resources as aliases, but the client cannot know that without some out-of-band agreement. (but see next comment)
So is it expected that people have to decide in advance which transport will be use for any given resource? The middlebox-traversal use case would seem to favor approaches where the client gets to decide what transport to use on the fly.
The way this is set up right now: Yes, the link tells you which transport to use.
Post by Ben Campbell
Post by Carsten Bormann
The solutions that people are talking about in our domain are about carrying transport alternatives around together.
E.g., see draft-silverajan-core-coap-protocol-negotiation-05.txt, which provides a way to find out about links from a set of links (the resource directory) while specifying a transport type. [It may be instructive to go through previous versions of this document just to see what we also have tried to do.]
So from an admittedly very quick scan, am I correct to assume that the directory described in that draft could be as “out-of-band” mechanism to declare resource aliases as I mentioned above?
Well, you go from a directory search to a set of links, not as a way to go from one link to another.
Other sources of links (hypermedia documents) would also need to provide alternatives whenever they are needed.
Post by Ben Campbell
So why not use that sort of mechanism to advertise the available transports for an authority, and at least allow the transport selection to be completely decoupled from the scheme?
We weren’t sure whether we wanted to support the trend “to use this URI, you need this ancillary information”.
It would be nice if we could keep the URL property for our URIs.
Post by Ben Campbell
If people really want to bind transport selection to the resource name, then some such mechanism seems to be a requirement to make the solution in this draft fit for purpose. But the transport-negotiation draft is not yet adopted by CORE. Does it make sense to publish this before that is well on it’s way to ready?
Generally, we already know how to ship around sets of links. What the transport-negotiation draft addresses is some additional functionality facilitating the bundling of these links in directories. So coap-tcp-tls will be useful today for OMA and OCF, but we’d like to have the bundling available for the future.
Post by Ben Campbell
Post by Carsten Bormann
What we have right now in draft-ietf-core-coap-tcp-tls is what we think is the least ugly way to solve the problem.
The WG is well aware about its problems.
We’d rather have a mechanism like transport hints, but we did not find a solution that would not need to update the web architecture.
At least some other protocols do this with DNS NAPTR records. I realize that may not be realistic for constrained devices (and I gather the protocol-negotiation draft attacks that same problem.) SIP, for example, can specify the transport with a URI parameter, which allows a URI to either specify a transport or to be transport-independent (by leaving off the parameter.)
Adding a level of indirection is not that useful in the constrained space — URIs are better if they are ready to use (many CoAP applications do not even use DNS). Shipping around URIs that need additional lookup to use them is not so useful. Having a multiple-transport URI that is compatible with (caches the same as) any of the single-transport ones would be great. I’m not sure SIP transport parameters to that.

Grüße, Carsten
Ben Campbell
2017-05-11 02:00:55 UTC
Permalink
Post by Carsten Bormann
Post by Ben Campbell
Post by Carsten Bormann
Hi Ben,
thank your for your review.
Post by Ben Campbell
2) It seems problematic to encode the transport choice in the URI
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.
URIs don’t have a good place to put in transport hints.
(The definition of a transport hint in a URI would be information that lets me set up specific transports without creating a separate resource each time the values of that transport hint differ.)
Note that the main use case for the document at hand is one where the client may not be able to reach the server on the “main” transport (CoAP over UDP), so negotiation/upgrade(*) mechanisms are not solving the problem.
That’s exactly what I mean by “a primary motivation”. As defined, the name of a resource declares the transport. So if I have a “coap” scheme resource that I cannot reach over UDP, I cannot simply switch to TCP and reach that same resource, even if the server supports both UDP and TCP. I suppose the server could treat the two resources as aliases, but the client cannot know that without some out-of-band agreement. (but see next comment)
So is it expected that people have to decide in advance which transport will be use for any given resource? The middlebox-traversal use case would seem to favor approaches where the client gets to decide what transport to use on the fly.
The way this is set up right now: Yes, the link tells you which transport to use.
I’m confused at how this mechanism addresses the middlebox problem it purports to solve. Is the server expected to know in advance whether all of the clients are behind UDP-eating middleboxes? What if a client moves back and forth from behind such a middlebox?

And how are the cross-transport proxies described in this draft supposed to work at all, if a resource can only be reached over one transport?
Post by Carsten Bormann
Post by Ben Campbell
Post by Carsten Bormann
The solutions that people are talking about in our domain are about carrying transport alternatives around together.
E.g., see draft-silverajan-core-coap-protocol-negotiation-05.txt, which provides a way to find out about links from a set of links (the resource directory) while specifying a transport type. [It may be instructive to go through previous versions of this document just to see what we also have tried to do.]
So from an admittedly very quick scan, am I correct to assume that the directory described in that draft could be as “out-of-band” mechanism to declare resource aliases as I mentioned above?
Well, you go from a directory search to a set of links, not as a way to go from one link to another.
Other sources of links (hypermedia documents) would also need to provide alternatives whenever they are needed.
But do I understand correctly that with the transport negotiation draft, a server could advertise in such a directory that it was reachable over alternative transports? Wouldn’t that effectively mean that all of it’s resources are aliased for that alternative transport?
Post by Carsten Bormann
Post by Ben Campbell
So why not use that sort of mechanism to advertise the available transports for an authority, and at least allow the transport selection to be completely decoupled from the scheme?
We weren’t sure whether we wanted to support the trend “to use this URI, you need this ancillary information”.
It would be nice if we could keep the URL property for our URIs.
Post by Ben Campbell
If people really want to bind transport selection to the resource name, then some such mechanism seems to be a requirement to make the solution in this draft fit for purpose. But the transport-negotiation draft is not yet adopted by CORE. Does it make sense to publish this before that is well on it’s way to ready?
Generally, we already know how to ship around sets of links. What the transport-negotiation draft addresses is some additional functionality facilitating the bundling of these links in directories. So coap-tcp-tls will be useful today for OMA and OCF, but we’d like to have the bundling available for the future.
Post by Ben Campbell
Post by Carsten Bormann
What we have right now in draft-ietf-core-coap-tcp-tls is what we think is the least ugly way to solve the problem.
The WG is well aware about its problems.
We’d rather have a mechanism like transport hints, but we did not find a solution that would not need to update the web architecture.
At least some other protocols do this with DNS NAPTR records. I realize that may not be realistic for constrained devices (and I gather the protocol-negotiation draft attacks that same problem.) SIP, for example, can specify the transport with a URI parameter, which allows a URI to either specify a transport or to be transport-independent (by leaving off the parameter.)
Adding a level of indirection is not that useful in the constrained space — URIs are better if they are ready to use (many CoAP applications do not even use DNS). Shipping around URIs that need additional lookup to use them is not so useful. Having a multiple-transport URI that is compatible with (caches the same as) any of the single-transport ones would be great. I’m not sure SIP transport parameters to that.
For SIP URIs, two URIs with explicit transport parameters with different values do not match. But a SIP URI with a transport parameter matches an otherwise identical one with no transport parameter.

Thanks,

Ben.
Carsten Bormann
2017-05-10 19:38:28 UTC
Permalink
Hi Ben,

now for the other parts.
Post by Ben Campbell
----------------------------------------------------------------------
----------------------------------------------------------------------
1) This draft removes the reliability and ordering features COAP when
used
over reliable transports, under the assumption that the transport will
provide.
Yes.
Post by Ben Campbell
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).
Post by Ben Campbell
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.
There is no guarantee in any of the transports. End-to-end semantics require end-to-end support.
Post by Ben Campbell
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.
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 .)
Post by Ben Campbell
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.
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.
Post by Ben Campbell
2) […]
(See previous message.)
Post by Ben Campbell
----------------------------------------------------------------------
----------------------------------------------------------------------
3.2: I agree with Adam that this length scheme seems very complex for
the
return
(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.
Post by Ben Campbell
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?
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.
Post by Ben Campbell
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?
Reference [HomeGateway] may be useful here. Adaptive algorithms are probably going to have the best performance here.
Post by Ben Campbell
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?
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.
Post by Ben Campbell
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.
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?
Post by Ben Campbell
4.2: Is it really worth making the framing code behave differently for
WebSocket than for TCP?
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.
Post by Ben Campbell
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.)
Some CSM capability indicating options are that way, yes (e.g., the Block capability).
Why would such a capability go away during a connection?
Post by Ben Campbell
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.
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
Post by Ben Campbell
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.)
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.
Post by Ben Campbell
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.
Of course, we will follow the wisdom of the IESG of how to handle this.
Post by Ben Campbell
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.
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.
Post by Ben Campbell
Figures 7 and 8: "Payload (if any)" - Can we assume that if one uses
either
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...
Post by Ben Campbell
3.3: Is the guidance about what errors to return if you don't implement
a
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.
Post by Ben Campbell
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
:-)
Right. Diminishing returns, though.
Post by Ben Campbell
5.3: "One CSM MUST be sent by both endpoints...": s/both/each
Good point.
Post by Ben Campbell
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.
OK, “update” is not the right word them.
Post by Ben Campbell
This could easily be fixed by changing that to something to the effect
of
"When using TCP, this step changes to …"
Good point.
Post by Ben Campbell
Appendix A: Why is this an appendix? Updates to a standards track RFC
seem to
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
Ben Campbell
2017-05-11 02:07:10 UTC
Permalink
Post by Carsten Bormann
Hi Ben,
now for the other parts.
Post by Ben Campbell
----------------------------------------------------------------------
----------------------------------------------------------------------
1) This draft removes the reliability and ordering features COAP when
used
over reliable transports, under the assumption that the transport will
provide.
Yes.
Post by Ben Campbell
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).
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.
Post by Carsten Bormann
Post by Ben Campbell
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.
There is no guarantee in any of the transports. End-to-end semantics require end-to-end support.
Post by Ben Campbell
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.
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 .)
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.
Post by Carsten Bormann
Post by Ben Campbell
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.
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?
Post by Carsten Bormann
Post by Ben Campbell
2) […]
(See previous message.)
Post by Ben Campbell
----------------------------------------------------------------------
----------------------------------------------------------------------
3.2: I agree with Adam that this length scheme seems very complex for
the
return
(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.
Post by Ben Campbell
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?
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.
Post by Ben Campbell
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?
Reference [HomeGateway] may be useful here. Adaptive algorithms are probably going to have the best performance here.
Post by Ben Campbell
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?
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.
Post by Ben Campbell
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.
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?
Post by Ben Campbell
4.2: Is it really worth making the framing code behave differently for
WebSocket than for TCP?
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.
Post by Ben Campbell
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.)
Some CSM capability indicating options are that way, yes (e.g., the Block capability).
Why would such a capability go away during a connection?
Post by Ben Campbell
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.
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
Post by Ben Campbell
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.)
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.
Post by Ben Campbell
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.
Of course, we will follow the wisdom of the IESG of how to handle this.
Post by Ben Campbell
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.
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.
Post by Ben Campbell
Figures 7 and 8: "Payload (if any)" - Can we assume that if one uses
either
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...
Post by Ben Campbell
3.3: Is the guidance about what errors to return if you don't implement
a
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.
Post by Ben Campbell
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
:-)
Right. Diminishing returns, though.
Post by Ben Campbell
5.3: "One CSM MUST be sent by both endpoints...": s/both/each
Good point.
Post by Ben Campbell
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.
OK, “update” is not the right word them.
Post by Ben Campbell
This could easily be fixed by changing that to something to the effect
of
"When using TCP, this step changes to …"
Good point.
Post by Ben Campbell
Appendix A: Why is this an appendix? Updates to a standards track RFC
seem to
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
Carsten Bormann
2017-05-11 13:55:26 UTC
Permalink
Post by Ben Campbell
Post by Carsten Bormann
Hi Ben,
now for the other parts.
Post by Ben Campbell
----------------------------------------------------------------------
----------------------------------------------------------------------
1) This draft removes the reliability and ordering features COAP when
used
over reliable transports, under the assumption that the transport will
provide.
Yes.
Post by Ben Campbell
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).
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.
Post by Ben Campbell
Post by Carsten Bormann
Post by Ben Campbell
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.
There is no guarantee in any of the transports. End-to-end semantics require end-to-end support.
Post by Ben Campbell
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.
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 .)
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).
Post by Ben Campbell
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.
Post by Ben Campbell
Post by Carsten Bormann
Post by Ben Campbell
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.
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?
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.
Post by Ben Campbell
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
Ben Campbell
2017-05-11 15:14:33 UTC
Permalink
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) [removed, please see update in comments]

2) It seems problematic to encode the transport choice in the URI
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:
----------------------------------------------------------------------

Update: I removed point 1 from my discuss. But I do still think it would
be useful to add a paragraph about how COAP reliability features are only
hop-by-hop.

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.
Adam Roach
2017-05-11 21:32:35 UTC
Permalink
2) It seems problematic to encode the transport choice in the URI 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.
I've been turning this over in my mind, and I think there are two
problems here. The fundamental problem is that this document is encoding
all kinds of protocol options into the URI scheme, which is an
architecturally worrisome precedent for *all* URI-using protocols,
current and future (by which I mean to say I don't think it's in CORE's
unilateral purview to decide this is okay). This problem is compounded
for CoAP in particular by treating the resource spaces associated with
each scheme as distinct.

I don't know whether the second issue is intentional or just a
misunderstanding about whether it is allowable to have different schemes
share a resource space (it is; cf. [1]), but I think we can come up with
a solution to the first problem that allows the second to become moot.

Looking to what we've done elsewhere in the IETF: considering the
present moment, recent past, and near future, we effectively have six
protocols in the wild for securely retrieving hypermedia across the
Internet: HTTP 1.x, SPDY1, SPDY2, SPDY3, H2, and QUIC. Note that these
protocols vary in syntax, semantics, and even transport-layer protocols.
The URI schemes for these six different protocols are https, https,
https, https, https, and https, respectively.

I think that's a good model. One pleasant advantage of this model is
that it completely eliminates the resource space issue I describe above.


Concretely, then, I propose that the URI schemes in this document be
assigned as follows:

For CoAP over TCP: coap

For CoAP over TLS over TCP: coaps

For CoAP over WS: coap

For CoAP over WSS: coaps


We then make UDP support mandatory to implement [2]. Now, let's talk
about TCP. I'm leaving WebSockets out of this description for a moment,
for reasons that I will explain later.

The general process for accessing a CoAP resource would be: try to
contact the remote node over UDP using a Confirmable message. After some
reasonable timespan (I would propose just prior to the third
transmission [second retransmission] of a message), if no ACK had been
received, those nodes that support TCP would try to initiate a TCP
connection (same host, same port, different transport) in parallel with
the third UDP transmission. If the TCP connection succeeds, abandon the
UDP attempts and start the transaction over on the TCP connection [3].

Two additionally proposed minor details on this scheme that I think
increase its appeal:

1. Nodes SHOULD cache, on a per-authority basis, whether UDP failed
(but TCP worked) in the past; and, if such a failure was observed
within a reasonable timeframe (hours or maybe days), use TCP instead
of UDP for subsequent contact. This cache would be flushed whenever
an IP address or routing table change is observed.

2. Nodes SHOULD allow configuration, both globally and on a
per-authority basis, to skip the UDP attempt, so as to optimize
connection times when UDP is administratively known to be nonviable
or otherwise undesirable.


Turning now to WebSockets. As far as I can tell, the use of WebSockets
is intended for a radically different deployment architecture than TCP
-- it looks very much like TCP is meant to accommodate one or both of
the parties being a constrained node, while WebSockets clearly is not:
there is no way it makes sense for a constrained device to implement
CoAP over WebSockets over HTTP on the conceit that it's simpler than
using HTTP. So, this means that CoAP/WebSockets is intended to run only
between two high-powered network hosts.

(I'd like to take a quick pause to say that these radically different
use cases suggest that it would be a Really Good Idea to split
CoAP/WebSockets out into its own document that builds on top of the
CoAP/TCP document.)

Okay, so let's try to back out an architecture of *why* you have two
non-contrained hosts using CoAP over WebSockets. Clearly, one of them is
a browser, or you'd just use straight-up CoAP, right? In fact, the
WebSockets client has to be the browser here. Further, if this is simply
a browser sending and receiving data to and from a server, there are
already a host of well-defined and broadly-deployed web technologies
that they could use instead of CoAP.

That means that the the only sensible conclusion is that the server is
one of: (a) a proxy for constrained device(s) that the browser wants to
contact, (b) a proxy for non-constrained device(s) that speak only CoAP
(presumably so constrained devices can also connect to it), or (c) both.
In all three cases, the proxy needs to have its own mapping that
converts from resources at its own authority to the corresponding
resources on the authority/ies for which is is serving as a proxy. This
is important, and we'll come back to it later.

As far as I can tell, that is the *only* context in which one might use
CoAP/WebSockets. I mean, if there's some other architecture that makes
sense here, I'd like to hear about it, but I think the logic above is
pretty sound.

In that context, then: a CoAP node implemented inside a web browser that
gets ahold of a coap: or coaps: URI can do precisely one thing: use
WebSockets to connect to the authority, using the CoAP/WebSockets
semantics defined in this document. It can't try UDP or TCP, because
these affordances aren't available from a web execution context. So if
the authority in the URL doesn't support CoAP/WebSockets, the client is
done.

Now, what about other, non-browser nodes that happen to get ahold of
these URIs? Well, now we're back to the fact that we made UDP MTI: these
same servers are listening for normal CoAP over UDP (and maybe TCP, if
they want to). So, remember how we said that this thing is necessarily a
proxy fronting other resources, and it has its own mapping from its
local resources to remote ones? That's what makes the whole UDP and TCP
thing work: it just needs to act like the same proxy for CoAP/UDP and
CoAP/TCP as it does for CoAP/WS.

/a

_____

[1] RFC section 4.1: "SIP and SIPS URIs that are identical except for
the scheme itself (e.g., sip:***@example.com and
sips:***@example.com) refer to the same resource."

[2] This is, I think, architecturally consistent with what's already
been done. In fact, this may already be the case; I can't quickly find
language covering this.

[3] The operation on the TCP connection would need to use the same
Message ID as the UDP attempts did, to ensure idempotency -- it's
possible that one or more of the transmitted UDP packets did make it to
the remote node, but the ACKs did not arrive back at the originator.
This does necessitate un-removing the Message ID field from TCP, but I
think that's a Good Thing anyway.
Ben Campbell
2017-05-11 22:15:55 UTC
Permalink
2) It seems problematic to encode the transport choice in the URI 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.
I've been turning this over in my mind, and I think there are two problems here. The fundamental problem is that this document is encoding all kinds of protocol options into the URI scheme, which is an architecturally worrisome precedent for *all* URI-using protocols, current and future (by which I mean to say I don't think it's in CORE's unilateral purview to decide this is okay). This problem is compounded for CoAP in particular by treating the resource spaces associated with each scheme as distinct.
I don't know whether the second issue is intentional or just a misunderstanding about whether it is allowable to have different schemes share a resource space (it is; cf. [1]), but I think we can come up with a solution to the first problem that allows the second to become moot.
Looking to what we've done elsewhere in the IETF: considering the present moment, recent past, and near future, we effectively have six protocols in the wild for securely retrieving hypermedia across the Internet: HTTP 1.x, SPDY1, SPDY2, SPDY3, H2, and QUIC. Note that these protocols vary in syntax, semantics, and even transport-layer protocols. The URI schemes for these six different protocols are https, https, https, https, https, and https, respectively.
I think that's a good model. One pleasant advantage of this model is that it completely eliminates the resource space issue I describe above
For CoAP over TCP: coap
For CoAP over TLS over TCP: coaps
For CoAP over WS: coap
For CoAP over WSS: coaps
I agree this appears to be the right model. I also recall Carsten mentioning elsewhere that the WG had made an earlier architectural decision to encode transport in the URLs. If that’s really the case, I’d be interested in hearing the reasoning behind it. I am skeptical that said reasoning would still hold in light of the architectural problems with doing so that have been identified .
We then make UDP support mandatory to implement [2]. Now, let's talk about TCP. I'm leaving WebSockets out of this description for a moment, for reasons that I will explain later.
The general process for accessing a CoAP resource would be: try to contact the remote node over UDP using a Confirmable message. After some reasonable timespan (I would propose just prior to the third transmission [second retransmission] of a message), if no ACK had been received, those nodes that support TCP would try to initiate a TCP connection (same host, same port, different transport) in parallel with the third UDP transmission. If the TCP connection succeeds, abandon the UDP attempts and start the transaction over on the TCP connection [3].
• Nodes SHOULD cache, on a per-authority basis, whether UDP failed (but TCP worked) in the past; and, if such a failure was observed within a reasonable timeframe (hours or maybe days), use TCP instead of UDP for subsequent contact. This cache would be flushed whenever an IP address or routing table change is observed.
• Nodes SHOULD allow configuration, both globally and on a per-authority basis, to skip the UDP attempt, so as to optimize connection times when UDP is administratively known to be nonviable or otherwise undesirable.
While this probably falls under your second bullet, I would include the possibility of an out-of-band mechanism to determine which transport the server supports/prefers. For example, DNS. In particular, Carsten mentioned draft-silverajan-core-coap-protocol-negotiation, which I understand might eventually offer such a mechanism.
Turning now to WebSockets. As far as I can tell, the use of WebSockets is intended for a radically different deployment architecture than TCP -- it looks very much like TCP is meant to accommodate one or both of the parties being a constrained node, while WebSockets clearly is not: there is no way it makes sense for a constrained device to implement CoAP over WebSockets over HTTP on the conceit that it's simpler than using HTTP. So, this means that CoAP/WebSockets is intended to run only between two high-powered network hosts.
(I'd like to take a quick pause to say that these radically different use cases suggest that it would be a Really Good Idea to split CoAP/WebSockets out into its own document that builds on top of the CoAP/TCP document.)
Okay, so let's try to back out an architecture of *why* you have two non-contrained hosts using CoAP over WebSockets. Clearly, one of them is a browser, or you'd just use straight-up CoAP, right? In fact, the WebSockets client has to be the browser here. Further, if this is simply a browser sending and receiving data to and from a server, there are already a host of well-defined and broadly-deployed web technologies that they could use instead of CoAP.
That means that the the only sensible conclusion is that the server is one of: (a) a proxy for constrained device(s) that the browser wants to contact, (b) a proxy for non-constrained device(s) that speak only CoAP (presumably so constrained devices can also connect to it), or (c) both. In all three cases, the proxy needs to have its own mapping that converts from resources at its own authority to the corresponding resources on the authority/ies for which is is serving as a proxy. This is important, and we'll come back to it later.
As far as I can tell, that is the *only* context in which one might use CoAP/WebSockets. I mean, if there's some other architecture that makes sense here, I'd like to hear about it, but I think the logic above is pretty sound.
In that context, then: a CoAP node implemented inside a web browser that gets ahold of a coap: or coaps: URI can do precisely one thing: use WebSockets to connect to the authority, using the CoAP/WebSockets semantics defined in this document. It can't try UDP or TCP, because these affordances aren't available from a web execution context. So if the authority in the URL doesn't support CoAP/WebSockets, the client is done.
Now, what about other, non-browser nodes that happen to get ahold of these URIs? Well, now we're back to the fact that we made UDP MTI: these same servers are listening for normal CoAP over UDP (and maybe TCP, if they want to). So, remember how we said that this thing is necessarily a proxy fronting other resources, and it has its own mapping from its local resources to remote ones? That's what makes the whole UDP and TCP thing work: it just needs to act like the same proxy for CoAP/UDP and CoAP/TCP as it does for CoAP/WS.
/a
_____
[2] This is, I think, architecturally consistent with what's already been done. In fact, this may already be the case; I can't quickly find language covering this.
[3] The operation on the TCP connection would need to use the same Message ID as the UDP attempts did, to ensure idempotency -- it's possible that one or more of the transmitted UDP packets did make it to the remote node, but the ACKs did not arrive back at the originator. This does necessitate un-removing the Message ID field from TCP, but I think that's a Good Thing anyway.
Carsten Bormann
2017-05-12 09:48:05 UTC
Permalink
Hi Adam,

thank you for this design sketch.

I fully support your quest to find a solution that avoids resource siloing.

I’ll call the approach of trying out several transports at once “happy bearing balls” for now :-)
(We don’t have eyeballs in the IoT :-)

I’m still a bit nauseous from all that probing and caching (and negative caching). It sounds like a big deployment headache, and a way to add indeterminism and inexplicable delays into something that could have been very simple. Having a transport *hint* in the URI still sounds like a way to reduce this when the determination can already be made at the server side ([1]).

In the IoT space we typically have information from configuration and from places such as the Resource Directory that could enhance a URI with information about the best transport type to use for it (DNS is not always in use, by the way). Baking this into the way transports are selected goes further down the road that a URI is not by itself all you need to make the request, but to a certain extent that has always been the case by including a DNS name (which may be one reason why DNS is not as much in use with CoAP).
[3] The operation on the TCP connection would need to use the same Message ID as the UDP attempts did, to ensure idempotency -- it's possible that one or more of the transmitted UDP packets did make it to the remote node, but the ACKs did not arrive back at the originator. This does necessitate un-removing the Message ID field from TCP, but I think that's a Good Thing anyway.
How is a server supposed to find out two messages that reach it over different transports are actually the same?
Sure, including message-IDs would be one thing (which are otherwise of no use in TCP).
But what about two clients happening to use the same message-ID? The server would need to associate the copies of the request it got to the same client. This would require that the client uses matching ephemeral ports for UDP and TCP, and I don’t know how to get this through NATs (which are one of the big use cases we are addressing).

So I would like to de-emphasize the happy bearing balls for non-idempotent requests — there is usually something that a client wants to do with a server anyway before getting to those.

In summary: I like being able to do happy bearing balls. I’d also like to be able to not use it, based on transport hints.

Grüße, Carsten

[1] It seems you have those transport hints in SIP. But SIP doesn’t have to deal with URI resolution based on base URIs, so it has more freedom in putting parameters into the URI. The reason our transport information is in the scheme is that we couldn’t find a better place. I would love to hear there is.
Adam Roach
2017-05-12 14:57:27 UTC
Permalink
Post by Carsten Bormann
Hi Adam,
thank you for this design sketch.
I fully support your quest to find a solution that avoids resource siloing.
To be clear, while that's a goal here, it's far from the primary goal.
The high-order bit in my book is correctly dealing with what URI schemes
actually mean, since that has implications well beyond CoAP.
Post by Carsten Bormann
I’ll call the approach of trying out several transports at once “happy bearing balls” for now :-)
(We don’t have eyeballs in the IoT :-)
I’m still a bit nauseous from all that probing and caching (and negative caching).
The caching is an optimization with obvious trade-offs, and I'm more
than happy to leave it to implementations as to whether they think it's
something they need.
Post by Carsten Bormann
It sounds like a big deployment headache, and a way to add indeterminism and inexplicable delays into something that could have been very simple.
As you correctly point out above, there are no eyeballs involved. I
doubt that Things care about the occasional 15-second delay. In any
case, the configuration I propose is intended to shortcut these delays
if NATs are known to be a problem a priori.
Post by Carsten Bormann
Having a transport *hint* in the URI still sounds like a way to reduce this when the determination can already be made at the server side ([1]).
In the IoT space we typically have information from configuration and from places such as the Resource Directory that could enhance a URI with information about the best transport type to use for it (DNS is not always in use, by the way). Baking this into the way transports are selected goes further down the road that a URI is not by itself all you need to make the request, but to a certain extent that has always been the case by including a DNS name (which may be one reason why DNS is not as much in use with CoAP).
I really don't follow this paragraph.
Post by Carsten Bormann
[3] The operation on the TCP connection would need to use the same Message ID as the UDP attempts did, to ensure idempotency -- it's possible that one or more of the transmitted UDP packets did make it to the remote node, but the ACKs did not arrive back at the originator. This does necessitate un-removing the Message ID field from TCP, but I think that's a Good Thing anyway.
How is a server supposed to find out two messages that reach it over different transports are actually the same?
Sure, including message-IDs would be one thing (which are otherwise of no use in TCP).
But what about two clients happening to use the same message-ID? The server would need to associate the copies of the request it got to the same client. This would require that the client uses matching ephemeral ports for UDP and TCP, and I don’t know how to get this through NATs (which are one of the big use cases we are addressing).
So I would like to de-emphasize the happy bearing balls for non-idempotent requests — there is usually something that a client wants to do with a server anyway before getting to those.
It sounds like we can come up with something here, then -- perhaps
UDP&TCP clients would be required to make first contact using a request
that is inherently idempotent. (I mean, I have some other ideas about
how we could perform deduplication, but I'm sure you'd find them
distasteful for constrained implementations.)
Post by Carsten Bormann
In summary: I like being able to do happy bearing balls. I’d also like to be able to not use it, based on transport hints.
I'm fine with that in principle, but your transport hints can't be part
of your URI scheme. That's just not what schemes mean.

/a

Loading...