Subject: [6tisch] draft-ietf-6tisch-minimal-security: Error code and server state

From: Christian Amsüss <[email-masked]>
Date: Wed, 27 Mar 2019 18:29:23 +0100

Hello Mališa,

we've just talked about server state and the error codes sent with
subsequent join requests in [1], especially Sections 8.4.1 and Section
8.4.5. (Working group, please be aware that I have not read and
understood the full document but am responding to a particular question
here).

My understanding is that the pledge POSTs its Join_Request to the
server, initially without an Error, and receives a response. If it has
trouble acting on the response, it sends another request that includes
the original parameters plus an error object; the server may respond to
that with a more final error ("Sorry, then I can't help you either") or
by sending a different response ("OK, if you can't do X, here's a setup
that works without that"). The question is as whether that agrees with
the a RESTful design and to the stateless servers we aspire in CoRE.

The error handling as currently described requires the server to keep
around information about the previous request. That is not per se a
violation of the side effect rules of CoAP (as the request is a POST and
the server may change state as a result), but has non-idempotent POST
requests which are discouraged in CoRE, and could be avoided easily.

Suggestion: Chain errors in the requests
----------------------------------------

I suggest that only errors be sent in subsequent requests that are
self-descriptive, and not so much indicate "what happened" but more
"what the pledge can't do"; then the server does not need to remember
the history of each pledge's requests.

If that is to be played back-and-forth (and I understand there are up to
four attempts), this requires that the pledge can indicate more than one
thing that went wrong. As long as there is only one error field, if
(say) the client tells the server after the first round-trip that it
doesn't support option X and the server offers option Y instead, the
client could only indicate with the response that it won't support
option Y, and the server would happily give it X again. Making the error
field in the Join_Request a list would ease that, and might even allow
for fewer round-trips if the pledge can issue complaints about several
options in the first round-trip.

Having a list of errors does obviously increase complexity a little, and
it requires the client to keep track of things that it dislikes about
the server's previous responses. My impression is that pledges can
probably afford that (it's state of size that's limited by the number of
attempts it's willing to do, and is only kept during the joining
process), freeing the serve of keeping around state of every pledge for
some potentially-hard-to-tell time.

Suggestion: Require errors to be self-descriptive
-------------------------------------------------

With that alone, a stateless server can be constructed, though the
conceptualization would be a bit convoluted (the precise rules of
interpreting the error codes would be "Had I sent you this request with
one less error, your response would trigger error X in me") --
stateless, but not particularly elegant to think about or easy to act
on.

If the error codes could be limited to statements that are valid truths
irrespective of hypothetical answers, that would look cleaner but
supports only error codes that state such valid truths. Conceptually, it
would not so much be an "error" field but a "things I'm telling you in
advance I can't do".

Of the list in Table 4, I'd say that

* 0 is not applicable (it's a server response)
* 1 should not be expected to be recoverable, and in this model of
  thought becomes very fuzzy. ("Give me that, but I know I can't act on
  it...?")
* 2 is fine as long as it relates to the number of the option it doesn't
  understand but not the value (The statement would be "I don't support
  option X" -- something the pledge could have even said in advance).
* 3 is not good but can easily be fixed by indicating a key ID rather
  than an index in a list whose indices will change when the server
  tries to do better.
* 4 is fine (that, like with 2, is something the pledge could even have
  said in advance).

From the discussion before I take it that this is something that can
easily be fixed; if you want me to look at the changes you'd make to
accommodate this, I'd be happy to have a brief look. (Just please CC me,
I'm not actively reading the 6tisch list).

Have a good flight
Christian

[1]: https://tools.ietf.org/html/draft-ietf-6tisch-minimal-security-09

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

---

From: Mališa Vučinić <[email-masked]>
Date: Wed, 27 Mar 2019 23:29:01 +0100

Hello Christian,

Thank you for summarizing the discussion we had and proposing these changes. I have modified the text in order to reflect the email below by:
- encoding additional info as a CBOR array allowing multiple parameters to be transported within
- removing the previous error code which explicitly was referring to the state of a request
- renaming of Error object to Diagnostic, if you have a better naming proposal, please let me know
- encapsulating the entire link layer key object(s) that is unsupported by a given pledge. I believe this is the simplest handling from the pledge implementation point of view as it can simply memcpy the byte string received

I also did some minor edits to align the text in the rest of the document, the related diff is available at:
https://bitbucket.org/6tisch/draft-ietf-6tisch-minimal-security/branch/minimal-security-10?dest=minimal-security-10-goran#diff <https://bitbucket.org/6tisch/draft-ietf-6tisch-minimal-security/branch/minimal-security-10?dest=minimal-security-10-goran#diff>

Please let me know if you see any issue with this resolution.

Mališa

> On 27 Mar 2019, at 18:29, Christian Amsüss <[email-masked]> wrote:
> 
> Hello Mališa,
>

---

From: Christian Amsüss <[email-masked]>
Date: Thu, 28 Mar 2019 01:29:07 +0100

Hello Mališa,

> Thank you for summarizing the discussion we had and proposing these changes. I have modified the text in order to reflect the email below by:

I'm not sure I understand the distinction between "unsupported" and
"unexpected" parameters. Are they about having an unknown code vs.
having an unknown value? If so, the unexpected additional info should
include the full value in the diagnostic, and not only the label.

I don't quite see how the arrays come in here, especially given that I
didn't find the Diagnostic CDDL used anywhere in the updated document
(JoinRequest still only has Error). Is the intention here that there is
only one Diagnostic, with only one code and a list of values? With that
a pledge could say that it won't understand options X and Y, but it
can't say that it won't understand option X and can't use the link-layer
key Y.

(On an editorial note, the "Additional info type" could go away in
#table_diagnostic_codes, but given the above I think they should rathe
stay uint / uint (key_id) / Configuration, and have at some point a `?
8: [ +Diagnostic ]` or so).

> - renaming of Error object to Diagnostic, if you have a better naming proposal, please let me know

I'd call it UnsupportedConfigurations, but that's really a matter of
overall document terminology which I'm unfamiliar with.

Kind regards
Christian

---

From: Mališa Vučinić <[email-masked]>
Date: Thu, 28 Mar 2019 17:24:46 +0100

Hello Christian,

The intent was indeed to differentiate between “I cannot do what is requested with parameter X” and “I understand parameter X but not what you are asking me to do with it”. To avoid ambiguity, I now use the terms “unsupported” and “malformed” as code values.

Essentially, along the notes of your proposal I modified the text and specified two objects:

Unsupported_Configuration = [
       + parameter           : Unsupported_Parameter
]

Unsupported_Parameter = (
         code                : int,
         parameter_label     : int,
         parameter_value     : any
)

with code being either “Unsupported” or “Malformed”. In either case, parameter_label and parameter_value are returned. This structure also supports the signaling of individual link layer keys, as the "link-layer key set” parameter label can be signaled together with the subset of the original keys. 

Note that the message name carrying this response is still called Diagnostic Response message. The commit was squashed with the previous one and the diff is available at:
https://bitbucket.org/6tisch/draft-ietf-6tisch-minimal-security/branch/minimal-security-10?dest=minimal-security-10-goran#diff <https://bitbucket.org/6tisch/draft-ietf-6tisch-minimal-security/branch/minimal-security-10?dest=minimal-security-10-goran#diff>

Let me know what do you think.

Mališa

> On 28 Mar 2019, at 01:29, Christian Amsüss <[email-masked]> wrote:
> 
> Hello Mališa,
>