Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add discussion of and CoAP Options for CRI use in CoAP #81

Merged
merged 6 commits into from
Jan 19, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 211 additions & 5 deletions draft-ietf-core-href.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ normative:
IANA.uri-schemes:
BCP26:
-: ianacons
=: RFC8126
# =: RFC8126
IANA.core-parameters:
I-D.carpenter-6man-rfc6874bis: zonebis
RFC8610: cddl
Unicode:
Expand All @@ -91,7 +92,13 @@ memory size.
[^status]

[^status]: (This "cref" paragraph will be removed by the RFC editor:)\\
The present revision –14 of this draft picks up comments from the shepherd review.
The present revision –14 of this draft picks up comments from the
shepherd review and adds sections on CoAP integration and on `cri`
application-oriented literals for the Extended Diagnostic
Notation.\\
This revision still contains open issues and is intended to serve
as a snapshot while the processing of the shepherd review is being
completed.

--- middle

Expand Down Expand Up @@ -732,6 +739,7 @@ authority
normalization would turn the percent-encoding back to the unreserved
character that a dot is.)

{: #host-ip-to-uri}
The value of a `host-ip` item MUST be
represented as a string that matches the "IPv4address" or
"IP-literal" rule ({{Section 3.2.2 of RFC3986}}).
Expand Down Expand Up @@ -953,8 +961,189 @@ properties of UTF-8 make this a simple linear process.)
> text-pet-sequence elements for their representation typically need
> to process them byte by byte.

# CoAP Integration

This section discusses ways in which CRIs can be used in the context
of the CoAP protocol {{-coap}}.

## Converting Between CoAP CRIs and Sets of CoAP Options

This section provides an analogue to {{Sections 6.4 and 6.5 of -coap}}:
Computing a set of CoAP options from a request CRI {{decompose-coap}} and computing a
request CRI from a set of COAP options {{compose-coap}}.

This section makes use of the mapping between CRI scheme ids
and URI scheme names shown in {{scheme-map}}:

| CRI scheme id | URI scheme |
|---------------|------------|
| -1 | coap |
| -2 | coaps |
| -7 | coap+tcp |
| -8 | coaps+tcp |
| -9 | coap+ws |
| -10 | coaps+ws |
{: #scheme-map title="Mapping CRI scheme ids and URI scheme names"}


### Decomposing a Request CRI into a set of CoAP Options {#decompose-coap}

The steps to parse a request's options from a CRI »cri« are as
follows. These steps either result in zero or more of the Uri-Host,
Uri-Port, Uri-Path, and Uri-Query Options being included in the
request or they fail.

Where the following speaks of deriving a text-string for a CoAP Option
value from a data item in the CRI, the presence of any
`text-pet-sequence` subitem ({{pet}}) in this item fails this algorithm.

1. If »cri« is not an absolute CRI reference, then fail this
algorithm.

2. Translate the scheme id into a URI scheme name as per
{{scheme-map}}; if a scheme id not in this list is being used,
fail this algorithm.
Remember the specific variant of CoAP to be used based on this
URI scheme name.

3. If »cri« has a `fragment` component, then fail this algorithm.

4. If the `host` component of »cri« is a `host-name`, include a
Uri-Host Option and let that option's value be the text string
value of the `host-name`.

If the `host` component of »cri« is a `host-ip`, check whether
the IP address given represents the request's
destination IP address (and, if present, zone-id).
Only if it does not, include a Uri-Host Option, and let that
option's value be the text value of the URI representation of
the IP address, as derived in {{host-ip-to-uri}}.

5. If »cri« has a `port` component, then let »port« be that
component's unsigned integer value; otherwise, let »port« be
the default port number for the scheme.

6. If »port« does not equal the request's destination UDP port,
include a Uri-Port Option and let that option's value be »port«.

7. If the value of the `path` component of »cri« is empty or
consists of a single empty string, then move to the next step.

Otherwise, for each element in the »path« component, include a
Uri-Path Option and let that option's value be the text string
value of that element.

8. If »cri« has a `query` component, then, for each element in the
`query` component, include a Uri-Query Option and let that
option's value be the be the text string
value of that element.

### Composing a Request CRI from a Set of CoAP Options {#compose-coap}

The steps to construct a CRI from a request's options are as follows.
These steps either result in a CRI or they fail.


1. Based on the variant of CoAP used in the request, choose a
`scheme-id` as per table {{scheme-map}}. Use that as the first
value in the resulting CRI array.

2. If the request includes a Uri-Host Option, insert an
`authority` with its value determined as follows:
If the value of the Uri-Host Option is a `reg-name`, include
this as the `host-name`.
If the value is an IP-literal or IPv4address, extract any
`zone-id`, and represent the IP address as a byte string of
the correct length in `host-ip`, followed by any `zone-id`
extracted if present.
If the value is none of the three, fail this algorithm.

If the request does not include a Uri-Host Option, insert an
`authority` with `host-ip` being the byte string that
represents the request's destination IP address and,
if one is present in the request's destination, add a `zone-id`.

3. If the request includes a Uri-Port Option, let »port« be that
option's value. Otherwise, let »port« be the request's
destination UDP port.
If »port« is not the default port for the scheme, then insert
the integer value of »port« as the value of `port` in the
authority.
Otherwise, elide the `port`.

4. Insert a `path` component that contains an array built from
the text string values of the Uri-Path Options in the request,
or an empty array if no such options are present.

5. Insert a `query` component that contains an array built from
the text string values of the Uri-Query Options in the request,
or an empty array if no such options are present.


## CoAP Options for Forward-Proxies {#coap-options}

Apart from the above procedures to convert CoAP CRIs to and from sets
of CoAP Options, two additional CoAP Options are defined in {{Section
5.10.2 of -coap}} that support requests to forward-proxies:

* Proxy-Uri, and
* its more lightweight variant, Proxy-Scheme

This section defines analogues of these that employ CRIs and the URI
Scheme numering provided by the present specification.

### Proxy-CRI

| No. | C | U | N | R | Name | Format | Length | Default |
| TBD235 | x | x | - | | Proxy-Cri | opaque | 1-1023 | (none) |
{: #tab-proxy-cri title="Proxy-Cri CoAP Option"}

The Proxy-CRI Option carries an encoded CBOR data item that represents
an absolute CRI reference.
It is used analogously to Proxy-Uri as defined in {{Section 5.10.2
of -coap}}.
The Proxy-Cri Option MUST take precedence over any of the Uri-Host,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe "MUST NOT be used with Uri-Host and Proxy-Scheme" (maybe "it's an error", maybe "one must be ignored").

Maybe "MUST either not have path and query components (in which case Uri-Path and Uri-Query are allowed and just appended semantically), or not occur with those together in a message".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or go full-base, and allow also that there's only the scheme present (at which point Proxy-Scheme-Number becomes somewhat redundant).

Copy link
Member

@chrysn chrysn Dec 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Motivation here (because the comments above may sound more convinced of myself as it may sound):

In the URI mind set, the difference between sending a request directly and sending it through the proxy is:

  • Set the remote address to the proxy's
  • Add Proxy-Scheme
  • Add Uri-Host
    (and personally I've always discouraged Proxy-Uri)

If someone wants to do the same trick in the CRI mindset, they can either

  • do the same, but beware that IP literals in the URI host need to go through decimal or hex encoding, or
  • use Proxy-CRI, and suddenly add another switch where Uri-Path/-Query don't go into the message any more.

Not great, but also somewhat weird to make this more complicated. A Proxy-CRI that may be just scheme and authority would solve this. (As would having a dedicated CRI-SchemeAndAuthority option or a Cri-Host option that is to be combined with Proxy-SchemeNumber).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Examples:

  • Request in CoAP-over-TCP to a CoAP resource on a same-host proxcy as described in transport-indication:

    • GET Uri-Path: "foo", "bar", Proxy-Scheme: "coap" (the existing approach)
    • GET Uri-Path: "foo", "bar", Proxy-Scheme-Numeric: 0 (0 byte)
    • GET Uri-Path: "foo", "bar', Cri-SchemeAndAuthority: <<-1>> (1 byte)
    • GET Proxy-Cri is not an option b/c it can't implicitly state the authority.
  • Request through a proxy (any transport going forward to UDP literal):

    • GET Uri-Path: "foo", "bar", Proxy-Scheme: "coap", Uri-Host: "[2001:db8::1]" (a hex encoding implementers may dislike)
    • GET Uri-Path: "foo", "bar", Proxy-Scheme-Numeric: 0 (0 byte), Uri-Host: "[2001:db8::1]" (still same issue)
    • GET Uri-Path: "foo", "bar', Cri-SchemeAndAuthority: <<-1, h'20010db8...0001'>>
    • GET Proxy-Cri: <<-1, h'20010db8...0001', ["foo", "bar"]>>
  • Request through a proxy (any transport going forward to host name):

    • GET Uri-Path: "foo", "bar", Proxy-Scheme: "coap", Uri-Host: "example.com" (which is a bit string-y but not as bad as the IP literal)
    • GET Uri-Path: "foo", "bar", Proxy-Scheme-Numeric: 0 (0 byte), Uri-Host: "example.com" (still same issue)
    • GET Uri-Path: "foo", "bar', Cri-SchemeAndAuthority: <<-1, "example", "com">>
    • GET Proxy-Cri: <<-1, "example", "com", ["foo", "bar"]>>
  • OSCORE splitting of the Proxy-... options, when hitting Proxy-Cri <<0, "example", "com", ["foo", "bar"]>>
    (which this document will probably need to describe to follow the recommendation of OSCORE)

    • could be described as going through conversion to Uri, then split as per 8613, and possibly converted back
    • could be described as splitting the Proxy-Cri into Proxy-Scheme-Numeric: 0, Uri-Host: "example.com" (needs stringification of any IP literal, which we don't have in this case), and inner Uri-Path options
    • could be described as splitting the Proxy-Cri into Cri-SchemeAndAuthority <<-1, "example", "com">> and inner Uri-Path options (provided they even fit in Uri-Scheme, don't know what 8613 says about the equivalent case)

Uri-Port, Uri-Path or Uri-Query options, as well as over any
Proxy-Uri Option (each of which MUST NOT be
included in a request containing the Proxy-Cri Option).


### Proxy-Scheme-Number


| No. | C | U | N | R | Name | Format | Length | Default |
| TBD239 | x | x | - | | Proxy-Scheme-Number | uint | 0-3 | (none) |
{: #tab-proxy-scheme-number title="Proxy-Scheme-Number CoAP Option"}

The Proxy-Scheme-Number Option carries a URI Scheme Number represented as a
CoAP unsigned integer.
It is used analogously to Proxy-Scheme as defined in {{Section 5.10.2
of -coap}}.

Since CoAP Options are only defined as empty, (text) string, opaque
(byte string), or unsigned integer, the Option carries an unsigned
integer that gives the 1's complement of the URI Scheme Number, i.e.:

~~~ math
option value = -1 - scheme number
~~~

[^scheme-negative]

[^scheme-negative]: DISCUSS: Should the scheme registry simply use
unsigned numbers so it can be used here right away and the 1's
complement form is only used specifically for the nint that
`scheme-id` at the start of CRIs is?

[^location-scheme]

[^location-scheme]: TO DO: Discuss the need for a
location-scheme-numeric option?

# Implementation Status {#impl}

{::boilerplate rfc7942info}

With the exception of the authority=true fix, host-names split into
labels, and {{pet}}, CRIs are implemented in `https://gitlab.com/chrysn/micrurus`.
A golang implementation of version -10 of this document is found at:
Expand All @@ -981,8 +1170,8 @@ The security considerations discussed in {{Section 7 of RFC3986}} and
## CRI Scheme Numbers Registry {#cri-reg}

This specification defines a new "CRI Scheme Numbers" sub-registry in
the "CoRE Parameters" registry {{!IANA.core-parameters}}, with the
policy "Expert Review" ({{Section 4.5 of -ianacons}}).
the "CoRE Parameters" registry {{IANA.core-parameters}}, with the
policy "Expert Review" ({{Section 4.5 of RFC8126@-ianacons}}).
The objective is to have CRI scheme number values registered for all
registered URI schemes (Uniform Resource Identifier (URI) Schemes
registry), as well as exceptionally for certain text strings that the
Expand Down Expand Up @@ -1073,6 +1262,19 @@ IANA is requested to register the application-extension identifier

[^replace-xxxx]

## CoAP Option Numbers Registry

In the "CoAP Option Numbers" registry in the "CoRE Parameters" registry group [IANA.core-parameters],
IANA is requested to register the CoAP Option Numbers
as described in {{tab-iana-options}} and defined in {{coap-options}}.

| No. | Name | Reference |
| TBD235 | Proxy-Cri | RFC-XXXX |
| TBD239 | Proxy-Scheme-Number | RFC-XXXX |
{: #tab-iana-options title="New CoAP Option Numbers"}

[^replace-xxxx]

--- back

# Mapping Scheme Numbers to Scheme Names {#sec-numbers}
Expand Down Expand Up @@ -1332,7 +1534,11 @@ Changes from -09 to -14

* Add Christian Amsüss as contributor

* Add CBOR EDN application-extension "`cri`" (see {{edn-cri}} and {{cri-iana}}).
* Add CBOR EDN application-extension "`cri`" (see {{edn-cri}} and
{{cri-iana}}).

* Add Section on CoAP integration (and new CoAP Options Proxy-Cri and
Proxy-Scheme-Number).

Changes from -08 to -09

Expand Down
Loading