Subject: [core] Default values for Uri-Host with alternate transports

From: Carsten Bormann <[email-masked]>
Date: Sat, 4 Feb 2017 10:44:17 +0100

In CoAP, the Uri-Host option is optional in a request.
RFC 7252 section 5.10.1 defines a default value for Uri-Host (and
Uri-Port) based on the connection parameters (destination address and
port of the UDP packet).  The default value allows the client to not
send the Uri-Host if the value would match, and the server to
reconstruct a valid value for the host part of the URI being
addressed.  (I'm not mentioning Uri-Port again below, but similar
considerations apply for all the cases below.)

The definition based on the IP address/UDP port of course is not
applicable to alternate transports.  We are running into this right
now with CoAP over TCP/TLS/Websockets, and will do so again with CoAP
over SMS.

I think we should try to maintain the property as stated in 5.10.1
that "The default values for the Uri-Host and Uri-Port Options are
sufficient for requests to most servers".  More importantly,
reconstructing the URI based on the default value and then making a
request to that URI should not lead to a different place.

Note that for a reliable byte stream connection, we have to provide
default values for both directions, as both endpoints of the
connection can play both client and server.

For CoAP over TCP, it is proably OK to slightly adapt the definition
of the default to the IP address and port of the end of the connection
receiving the CoAP request.  (It is not quite clear that the acceptor of
the TCP connection could create a new connection by opening a TCP
connection to host/port of where it accepted the connection from, but
at least there is some address ownership.)

For WebSockets, that does not quite work.  The WebSocket hostname is
needed to make the connection, so that should also be the default
value of the Uri-Host for requests in the direction from the WebSocket
client to the WebSocket server.  What about the inverse direction?
(In practice, it is rather unlikely that a WebSockets client also is a
WebSockets server.  Still, it is very useful for the CoAP endpoint at
the WebSocket server to call back the CoAP endpoint at the Websocket
client, even if that is based on "You, whoever just called me"".  But
we don't have anonymous, ephemeral hosts in URIs.  Yet.)

For TLS, the TCP approach would also work, unless there is SNI -- in
that case the default in the direction TLS client to TLS server should
shift to the SNI name.  There is no way to indicate reverse SNI,
though -- can we be sure that is never needed?  Would a client
certificate change anything here?

In the last authors' call, we agreed to remove the signalling option
that would allow to set a different default URI host (used to be
called "Server-Name" analogously to SNI; a better name is
"Default-Uri-Host"), as we weren't aware of an implementation.
Do we need to keep it to solve anything of the above?

Grüße, Carsten

---

From: Klaus Hartke <[email-masked]>
Date: Sat, 4 Feb 2017 12:38:10 +0100

Carsten Bormann wrote:
> receiving the CoAP request.

+1

> client to the WebSocket server.

+1

> What about the inverse direction?

See below.

> shift to the SNI name.

+1

> There is no way to indicate reverse SNI,

Let's say a CoAP server is the initiator of a TCP/TLS/WebSockets
connection. Unless the CoAP server uses a client certificate in the
TLS case, the CoAP server does not have a name other than its
ephemeral transport address. This means a resource at this CoAP server
cannot be identified with an absolute URI, which requires an authority
component to be specified. Even if the CoAP server had a name, placing
this name in the authority component of the URI is not enough to
locate the CoAP server, because the CoAP server is most likely only
reachable through the established connection and unable to accept new
connections. Any third party would need to know that they actually
need to contact the acceptor of the TCP/TLS/WebSockets connection in
order to access a resource at the connection initiator. So the
possible options are to either limit interactions to the CoAP server
and the connection acceptor, or to let the connection acceptor make
the resources of the CoAP server available to third parties by acting
as a CoAP reverse proxy (or similar). This is what we describe as a
"third possible configuration" in [1].

> Do we need to keep it to solve anything of the above?

As far as I'm concerned the only use case for the Server-Name
signalling option is to allow a TCP connection initiator to set a
default value for the Uri-Host option in the requests it sends as a
CoAP client. I don't think this makes things more complicated or has a
high cost due to additional security considerations, but I don't have
a strong opinion if this little optimization should be included or
not.

Klaus

[1] https://tools.ietf.org/html/draft-savolainen-core-coap-websockets-07#page-4

---

From: Brian Raymor <[email-masked]>
Date: Tue, 7 Feb 2017 01:31:01 +0000

This is tracked in https://github.com/core-wg/coap-tcp-tls/issues/108. I'd welcome *broader* WG discussion for this issue. It's the remaining issue that's blocking coap-tcp-tls-06.

On Saturday, February 4, 2017 1:44 AM, Carsten Bormann wrote:

> For WebSockets, that does not quite work.  The WebSocket hostname is needed to make the connection, so that should also be the default value of the Uri-Host for requests in the direction from the WebSocket client to the WebSocket server.  

There's already text in the WD for this case:

    The WebSocket client includes the hostname of the WebSocket server
    in the Host header field of its handshake as per {{RFC6455}}. The Host
    header field also indicates the default value of the Uri-Host Option in
    requests from the WebSocket client to the WebSocket server.

> In the last authors' call, we agreed to remove the signalling option that would allow to set a different default URI host (used to be called "Server-Name" analogously to SNI; a better name is "Default-Uri-Host"), as we weren't aware of an implementation.

I don't see the need if appropriate defaults are adequately specified. Most of the related language in the Default-Uri-Host was to describe the "base values" for Uri-Host based on the transport - the values which are used if Default-Uri-Host (aka Server-Name) is never sent.

---

From: Brian Raymor <[email-masked]>
Date: Fri, 10 Feb 2017 01:05:11 +0000

I've submitted a pull request based on the suggestions from Carsten and Klaus - https://github.com/core-wg/coap-tcp-tls/pull/113.

I'm curious if there's another alternative - to simplify and not support the Uri-* options on reliable transports. 

If the main scenario as noted in RFC7252 is " Explicit Uri-Host and Uri-Port Options are typically used when an endpoint hosts multiple virtual servers", 
then as Klaus noted in the original TRAC issue - https://trac.ietf.org/trac/core/ticket/391, this is less relevant for CoAP over reliable transports (with perhaps the exception of CoAP over TCP):

    In CoAP over WebSockets, the virtual server is specified during the WebSocket handshake in the Host
    header field. The Uri-Host Option is therefore not needed. A client wishing to talk to multiple virtual
    servers running on the same IP address has to open one WebSocket connection to each virtual server ...

    In CoAP over TLS we have the SNI extension, so I would expect that CoAP over TLS behaves like CoAP
    over WebSockets: no Uri-Host Option in requests, one connection to each virtual server.

Carsten called out the same scenario in a related discussion on https://www.ietf.org/mail-archive/web/6tisch/current/msg02195.html:

     (The Uri-Host option actually is about the destination of the message, to distinguish several servers that might share an IP address/port number.)

Thoughts? How are early CoAP over TCP implementations using these options?

...Brian

-----Original Message-----
From: core [mailto:[email-masked]] On Behalf Of Brian Raymor
Sent: Monday, February 6, 2017 5:31 PM
To: Carsten Bormann <[email-masked]>; [email-masked] WG <[email-masked]>
Subject: Re: [core] Default values for Uri-Host with alternate transports

_______________________________________________
core mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/core

---

From: Klaus Hartke <[email-masked]>
Date: Fri, 10 Feb 2017 13:43:22 +0100

> I'm curious if there's another alternative - to simplify and not support the Uri-* options on reliable transports.

I assume you mean Uri-Host and Uri-Port when you say Uri-*, because
not supporting Uri-Path and Uri-Query does not make sense.

> " Explicit Uri-Host and Uri-Port Options are typically used when an endpoint hosts multiple virtual servers"

Uri-Host and Uri-Port are also used together with Uri-Scheme when
talking to a CoAP forward proxy.

> Thoughts?

IMO we should aim for consistency. There are three decisions to be made:

(Survey made is less than 5 minutes, please correct me if I'm wrong.)

1)

Virtual servers are supported
-or-
Virtual servers are not supported

* CoAP over UDP: yes
* CoAP over DTLS: yes
* CoAP over TCP: ?
* CoAP over TLS: yes
* CoAP over WebSockets: yes
* HTTP/1.1 over TCP: yes
* HTTP/1.1 over TLS: yes
* HTTP/2 over TCP: yes
* HTTP/2 over TLS: yes

I think it's obvious what CoAP over TCP should do.

2)

Server name in each request
-or-
Server name during connection setup

* CoAP over UDP: each request
* CoAP over DTLS: connection setup
* CoAP over TCP: ?
* CoAP over TLS: connection setup
* CoAP over WebSockets: connection setup
* HTTP/1.1 over TCP: each request
* HTTP/1.1 over TLS: both
* HTTP/2 over TCP: both
* HTTP/2 over TLS: both

For CoAP over TCP, server name during connection setup would be more
efficient, but server name in each request is probably fine, too.

3)

One connection per virtual server
-or-
Connection can be reused for multiple virtual servers with the same IP address

* CoAP over UDP: n/a
* CoAP over DTLS: RFC 7252 does not specify this, so most likely one
connection per virtual server
* CoAP over TCP: ?
* CoAP over TLS: ?
* CoAP over WebSockets: ?
* HTTP/1.1 over TCP: one connection per virtual server
* HTTP/1.1 over TLS: one connection per virtual server
* HTTP/2 over TCP: connection can be reused [1]
* HTTP/2 over TLS: connection can be reused [1]

I don't have a strong opinion on this.

Klaus

[1] https://tools.ietf.org/html/rfc7540#section-9.1.1

---

From: Carsten Bormann <[email-masked]>
Date: Fri, 10 Feb 2017 11:17:07 -0500

When discussing this, please don't forget the inverse direction -- there is no guidance even in ws or TLS what the URI-host should be. This needs a default. 

Sent from mobile

> On 10 Feb 2017, at 07:43, Klaus Hartke <[email-masked]> wrote:
> 
> Brian Raymor wrote:

---

From: Brian Raymor <[email-masked]>
Date: Fri, 10 Feb 2017 23:18:19 +0000

Since there are multiple, early implementations of CoAP over TCP in the wild, I continue to be curious
about the design choices that they've made which might help us make an informed decision. 

On Friday, February 10, 2017 8:17 AM, Carsten Bormann wrote:

> When discussing this, please don't forget the inverse direction --
>  there is no guidance even in ws or TLS what the URI-host should be. This needs a default. 

The difficulty in this case is offering a realistic and useful default without too many caveats. As you noted in your earlier message:

> (It is not quite clear that the acceptor of the TCP connection could create a new connection by opening a TCP connection to host/port of where
> it accepted the connection from, but at least there is some address ownership.)

> (In practice, it is rather unlikely that a WebSockets client also is a WebSockets server.  Still, it is very useful for the CoAP endpoint at the WebSocket server to call
> back the CoAP endpoint at the Websocket client, even if that is based on "You, whoever just called me"".  
> But we don't have anonymous, ephemeral hosts in URIs.  Yet.)

> There is no way to indicate reverse SNI, though -- can we be sure that is never needed?  Would a client certificate change anything here?

...Brian

---

From: Jim Schaad <[email-masked]>
Date: Fri, 10 Feb 2017 15:44:19 -0800

Reading this makes me more worried about the fact that the OSCOAP specification is currently setup to make the implicit endpoint explicit.

The fact that this can cause problems when going in the forward direction, the presence of a NAT (somethings a good thing even for IPv6) will mess this up when looking at implicit rules.   If you start looking at the reverse rules and still try to be implicit, then trying to get an explicit, and correct, URL is going to be even harder.

I should look to see if the tcp draft has the ability to say - if you send me a request I will treat it as if it came on port X rather than on the port I am sending from. 

This really re-enforces my opinion that OSCOAP should only validate the explicit rather than the implicit URI-* fields.

Jim

> From: core [mailto:[email-masked]] On Behalf Of Carsten Bormann
> Sent: Saturday, February 4, 2017 1:44 AM
> To: [email-masked] WG <[email-masked]>
> Subject: [core] Default values for Uri-Host with alternate transports
> 
> Uri-Port) based on the connection parameters (destination address and port
> of the UDP packet).  The default value allows the client to not send the Uri-
> Host if the value would match, and the server to reconstruct a valid value for
> the host part of the URI being addressed.  (I'm not mentioning Uri-Port again
> below, but similar considerations apply for all the cases below.)
> 
> The definition based on the IP address/UDP port of course is not applicable
> to alternate transports.  We are running into this right now with CoAP over
> TCP/TLS/Websockets, and will do so again with CoAP over SMS.
> 
> I think we should try to maintain the property as stated in 5.10.1 that "The
> default values for the Uri-Host and Uri-Port Options are sufficient for
> requests to most servers".  More importantly, reconstructing the URI based
> on the default value and then making a request to that URI should not lead
> to a different place.
> 
> Note that for a reliable byte stream connection, we have to provide default
> values for both directions, as both endpoints of the connection can play both
> client and server.
> 
> For CoAP over TCP, it is proably OK to slightly adapt the definition of the
> default to the IP address and port of the end of the connection receiving the
> CoAP request.  (It is not quite clear that the acceptor of the TCP connection
> could create a new connection by opening a TCP connection to host/port of
> where it accepted the connection from, but at least there is some address
> ownership.)
> 
> needed to make the connection, so that should also be the default value of
> the Uri-Host for requests in the direction from the WebSocket client to the
> WebSocket server.  What about the inverse direction?
> (In practice, it is rather unlikely that a WebSockets client also is a WebSockets
> server.  Still, it is very useful for the CoAP endpoint at the WebSocket server
> to call back the CoAP endpoint at the Websocket client, even if that is based
> on "You, whoever just called me"".  But we don't have anonymous,
> ephemeral hosts in URIs.  Yet.)
> 
> For TLS, the TCP approach would also work, unless there is SNI -- in that case
> the default in the direction TLS client to TLS server should shift to the SNI
> name.  There is no way to indicate reverse SNI, though -- can we be sure that
> is never needed?  Would a client certificate change anything here?
> 
> In the last authors' call, we agreed to remove the signalling option that would
> allow to set a different default URI host (used to be called "Server-Name"
> analogously to SNI; a better name is "Default-Uri-Host"), as we weren't
> aware of an implementation.

---

From: Jim Schaad <[email-masked]>
Date: Fri, 10 Feb 2017 15:46:38 -0800

> Sent: Thursday, February 9, 2017 5:05 PM
> Cc: Hannes Tschofenig <[email-masked]>; Klaus Hartke
> <[email-masked]>
> I've submitted a pull request based on the suggestions from Carsten and
> Klaus - https://github.com/core-wg/coap-tcp-tls/pull/113.
> 
> I'm curious if there's another alternative - to simplify and not support
the Uri-
> * options on reliable transports.

I am not sure that the rules would be applied to reliable transports, unless
that was totally end-to-end.  Starting on transport A and switching to
transport B is going to need the Uri-host field to make sure that it gets
routed correctly by the proxy.  

Jim

> 
> If the main scenario as noted in RFC7252 is " Explicit Uri-Host and
Uri-Port
> Options are typically used when an endpoint hosts multiple virtual
servers",
> then as Klaus noted in the original TRAC issue -
> https://trac.ietf.org/trac/core/ticket/391, this is less relevant for CoAP
over
> reliable transports (with perhaps the exception of CoAP over TCP):
> 
>     header field. The Uri-Host Option is therefore not needed. A client
wishing
> to talk to multiple virtual
>     In CoAP over TLS we have the SNI extension, so I would expect that
CoAP
> over TLS behaves like CoAP
>     over WebSockets: no Uri-Host Option in requests, one connection to
each
> virtual server.
> 
> Carsten called out the same scenario in a related discussion on
> https://www.ietf.org/mail-archive/web/6tisch/current/msg02195.html:
> 
>      (The Uri-Host option actually is about the destination of the
message, to
> distinguish several servers that might share an IP address/port number.)
> 
> This is tracked in https://github.com/core-wg/coap-tcp-tls/issues/108. I'd
> welcome *broader* WG discussion for this issue. It's the remaining issue
> that's blocking coap-tcp-tls-06.
> 
> WebSocket server.
that
> would allow to set a different default URI host (used to be called
"Server-
> Name" analogously to SNI; a better name is "Default-Uri-Host"), as we
> weren't aware of an implementation.
> I don't see the need if appropriate defaults are adequately specified.
Most of
> the related language in the Default-Uri-Host was to describe the "base
> values" for Uri-Host based on the transport - the values which are used if
> Default-Uri-Host (aka Server-Name) is never sent.
> 
>

---

From: Christian Amsüss <[email-masked]>
Date: Sat, 25 Feb 2017 12:59:45 +0100

Hi & sorry for being late to the party,

for the forward cases, I could well live with Uri-Host being
forbidden[1] on transports that have an established default host name
(especially since those tend to be those where that default host name is
verified cryptographically); at least, clients should be prepared for
hosts to go 4.03 on requests for other virtual hosts on a connection
where another host name was verified.

[1]: unless used in connection with Uri-Scheme

On Sat, Feb 04, 2017 at 10:44:17AM +0100, Carsten Bormann wrote:
> Still, it is very useful for the CoAP endpoint at
> we don't have anonymous, ephemeral hosts in URIs.  Yet.

The reverse case is more interesting to me, because it crops up in
deployment. (Where I'm encountering it is when a node is registering
with an RD from inside NAT).

URIs AFAIK do not support ephemeral identifiers -- but do we need any?
Protocols right now mostly do provide defaults. They might be unusable
globally, eg. coap+tcp://${ip}:${high_port}, coap+sms://${number},
coap+serial://com2 or maybe even coap+ws://${ip}:${high_port}, but they
are sufficient inside the application to parse responses. (I'll use
"application" for the side roughly synonymously with the acceptor side
her, ie. he who talks to a nameless one).

The problem arises when any of those addresses should be passed on
outside of the application. There, guidance for implementors might be
what we need rather than a protocol solution.

Once the application has identified which URIs are not usable globally
(and than can be tricky), a process similar to RDF's skolemization[2]
could be applied. Unless there is indication of a proper host name to
use (eg. using protocol-negotiation -- Bill, how's that coming along?)
and can be verified, the application would need to either mint a
hostname it can claim in DNS to furtheron be forward proxy for, or mint
a hostname it can at least be sure to be unique and unresolvable.

[2]: https://www.w3.org/TR/rdf11-concepts/#section-skolemization

An additional problem implementing this is that it might not be
immediately obvious whether the default address is usable at all. While
it is clear in the WebSocket case that nobody outside the WebSocket
server can contact the client directly, an incoming UDP packet might or
might not have been NATted. Do you know of any idea on how to clear that
up, short of having a third party try? For some protocols, the address
might be globally unique but accessibility not widespread (eg.
coap+sms), so maybe both passing on the address and an equivalent one
(again, protocol-negotiation) could be an option.

Best regards
Christian

-- 
To use raw power is to make yourself infinitely vulnerable to greater powers.
  -- Bene Gesserit axiom