Subject: [core] RFC 7252 - Forward Proxies

From: Achim Kraus <[email-masked]>
Date: Wed, 8 Jan 2020 13:50:59 +0100

Dear Core-List,

I'm currently try to spend some time in working on Californium's
"Forward Proxies" support according
https://tools.ietf.org/html/rfc7252#section-5.7.2.

Studying this section in combination with "Decomposing URIs into
Options" according https://tools.ietf.org/html/rfc7252#section-6.4 I'm
not sure, if 6.4 requires some more clarification considering 5.7.2.

Point 5 in 6.4 describes the processing for the host:

"5.  If the <host> component of |url| does not represent the request's
        destination IP address as an IP-literal or IPv4address, include a
        Uri-Host Option and let that option's value be the value of the
        <host> component of |url|, converted to ASCII lowercase, and then
        convert all percent-encodings ("%" followed by two hexadecimal
        digits) to the corresponding characters.

        NOTE: In the usual case where the request's destination IP
        address is derived from the host part, this ensures that a Uri-
        Host Option is only used for a <host> component of the form reg-
        name."

A informal description would be in my opinion, add the uri-host option,
if it's not the IP-literal of the destination (that assumes, that the
term "destination" refers to the actual proxy to send the request to).
But the text seems not to differentiate between the request's (which
maybe the proxy) and the URI destination (which will be the "final
destination", or something like that). I'm also not sure, what the "or
IPv4address" refers to.
For me it seems, that stick strict to 6.4 would cause different option
values, if a proxy is used and the "final destination" URI contains also
a (different) literal IP address. For me "strict" will then result in a
wrong request to the proxy.

Point 6 in 6.4 describes the processing for the port:

6.  If |url| has a <port> component, then let |port| be that
        component's value interpreted as a decimal integer; otherwise,
        let |port| be the default port for the scheme.

"6 ... otherwise": if a Proxy-Scheme is used, should that default port
be use? Or still the URI-Scheme's port? If the Proxy-Scheme is to be
considered, that default port maybe unclear/unknown by the client
implementation.

Best regards
Achim Kraus

---

From: Klaus Hartke <[email-masked]>
Date: Fri, 10 Jan 2020 10:47:57 +0100

Hej Achim!

Achim Kraus wrote:
> if it's not the IP-literal of the destination

Yes. A bit more precisely: The Uri-Host option is omitted in a request
if and only if its value equals the destination IP address of the
containing UDP datagram.

> (that assumes, that the

Yes. When sending a CoAP request to a forward proxy, the destination
of the UDP datagram is set to the IP address and UDP port number of
the forward proxy.

> destination", or something like that).

The CoAP options always encode the request URI, i.e., the URI of the
target resource. For example, if a client wants to GET a
representation of <coap://example.com:12345/.well-known/core>, then
the CoAP options always encode
<coap://198.51.100.1:12345/.well-known/core>, regardless of whether
the destination of the UDP datagram is (198.51.100.1, 12345) or the IP
address and UDP port number of a forward proxy.

> I'm also not sure, what the "or
> IPv4address" refers to.

This refers to the syntax rules for hosts in RFC 3986:

    host = IP-literal / IPv4address / reg-name

Example IP-literal: "[2001:db8::1]"
Example IPv4address: "198.51.100.1"
Example reg-name: "example.com"

> wrong request to the proxy.

This may need a bit clarification. When a request is intended for a
server, the request URI is encoded using the Uri-Host, Uri-Port,
Uri-Path, and Uri-Query options. (So, all the request URI components
are present, except for the scheme.) When a request is intended for a
forward proxy, the request URI is either encoded using the Proxy-Uri
option or the Proxy-Scheme, Uri-Host, Uri-Port, Uri-Path, and
Uri-Query options. (So, all the request URI components are present,
including the scheme.) Even though some of these options have the word
"Proxy" in their name, they still contain the components of the
request URI, not the IP address or UDP port number of the forward
proxy.

> considered, that default port maybe unclear/unknown by the client

It's the port number of the request URI (or, if the port number in the
request URI is omitted, the default port number for the scheme of the
request URI). It's not the port number of the forward proxy.

Does that answer your questions?

Best regards,
Klaus

---

From: Achim Kraus <[email-masked]>
Date: Sat, 11 Jan 2020 11:30:32 +0100

Hi Klaus,

thanks for your answers and reference explaining the term "IPv4address"!

 > For example, if a client wants to GET a representation of
<coap://example.com:12345/.well-known/core>, then the CoAP options
always encode <coap://198.51.100.1:12345/.well-known/core>, regardless
of whether the destination of the UDP datagram is (198.51.100.1, 12345)
or the IP address and UDP port number of a forward proxy.

In my understanding the, CoAP URI-Host option will be "example.com" and
not "198.51.100.1", otherwise hosts with multiple virtual server will
not be able to differentiate the logical request destination.

Also in my understanding, the port, IP-literal and IPv4address (the none
regname variants), are only included, if they differ from the
destination (which will be the porxy's address in case of a proxy).
Otherwise the note to point 5 of
https://tools.ietf.org/html/rfc7252#section-6.4

"NOTE: In the usual case where the request's destination IP
address is derived from the host part, this ensures that a Uri-
Host Option is only used for a <host> component of the form regname."

will not make sense.

 > It's the port number of the request URI (or, if the port number in
the request URI is omitted, the default port number for the scheme of
the request URI). It's not the port number of the forward proxy.

My question was rather, if it's the default port of the proxy scheme
(maybe http), or the requests coap-uri-scheme. My intention of the
question is:

"logical URI"  => "http://example.com/test"

Will be either:
Proxy-Scheme : "http"
CoAP-URI: "coap://example.com/test"
or
Proxy-Scheme : "http"
CoAP-URI: "coap://example.com:80/test"

Best regards

Achim Kraus

---

From: Klaus Hartke <[email-masked]>
Date: Sat, 11 Jan 2020 14:03:21 +0100

> not be able to differentiate the logical request destination.

Oh, sorry. I changed the example at some point from "example.com" to
"198.51.100.1" and apparently didn't change all instances. Here's the
corrected example:

   If a client wants to GET a representation of
   <coap://198.51.100.1:12345/.well-known/core>,
   then the CoAP options always encode
   <coap://198.51.100.1:12345/.well-known/core>,
   regardless of the destination of the UDP datagram.

Of course, the same is true for "example.com":

   If a client wants to GET a representation of
   <coap://example.com:12345/.well-known/core>,
   then the CoAP options always encode
   <coap://example:12345/.well-known/core>,
   regardless of the destination of the UDP datagram.

> destination (which will be the porxy's address in case of a proxy).

Yes, exactly. In pseudo-code:

  |url| = the request URI
  |scheme| = the <scheme> component of |url|
  |host| = the <host> component of |url|
  if the <port> component of |url| is present then
    |port| = the <port> component of |url|
  else
    |port| = the default port number for |scheme|
  endif

  if a forward-proxy is configured then
    include a Proxy-Scheme option with value |scheme|
    |transfer-protocol| = the protocol of the forward proxy
    |destination-host| = the IP address of the forward proxy
    |destination-port| = the port number of the forward proxy
  else
    do not include a Proxy-Scheme option
    |transfer-protocol| = the protocol indicated by |scheme|
    |destination-host| = |host| resolved to an IP address
    |destination-port| = |port|
  endif

  if |host| equals |destination-host| then
    do not include a Uri-Host option
  else
    include a Uri-Host option with value |host|
  endif

  if |port| equals |destination-port| then
    do not include a Uri-Port option
  else
    include a Uri-Port option with value |port|
  endif

(Necessary data conversions omitted for brevity.)

> (maybe http), or the requests coap-uri-scheme.

It's the default port number for the scheme of the request URI.

Klaus

---

From: Achim Kraus <[email-masked]>
Date: Sun, 12 Jan 2020 13:21:37 +0100

Hi Klaus,

thanks again for the clarifications!

best regards
Achim