Subject: [Lwip] Implementers questionnaire for draft-ietf-lwig-coap

From: "Kovatsch Matthias" <[email-masked]>
Date: Tue, 14 Apr 2015 02:06:54 +0000

Dear implementers

Thanks for responding to my call. I would like to ask you a few questions to assess the statements in draft-ietf-lwig-coap and hopefully identify a few gaps in the guidance. The following questions resemble the draft structure:

1.       Message Processing
Which approach did you choose and why, on-the-fly processing (keeping header fields and options encoded in local memory) or internal data structure (a native struct/object that is serialized on send)? It would be important to add the context of your implementation and decision: is it optimized for memory size, throughput, or usability?
Is there a third approach or an alternative optimization goal?

2.       Duplicate Rejection
Have you implemented full duplicate rejection with timers? Or do you rely on idempotency and application-specific handling of duplicates?
Again the context of your implementation and decision is interesting here.

3.       Token Usage
There has been continuous confusion about token usage on the mailing list and during interop events (e.g., in combination with blockwise transfers). Is there something you consider underspecified in RFC7252 or hard to get right (e.g., coping with reboots)?

4.       Programming Model
Did you use a model for embedded implementations that is not event-driven? Which is it and why did you choose it?
Is the listing of different resource types and their specific requirements useful to you?

5.       Optimizations
Is the text in Section 3 comprehensible?
Do you have further optimizations that you want to share?

6.       Alternative Configurations
Did you tweak any of the transmission parameters in your implementation?
Do you use IPv4 and did you run into problems when deploying your implementations?

We would really appreciate your input on this. I also might come up with further questions for a future revision of the draft.

Best regards
Matthias

---

From: Olaf Bergmann <[email-masked]>
Date: Wed, 22 Apr 2015 11:32:24 +0200

Hi Matthias,

here is the input for libcoap, garnished with a few editorial remarks
while reading the respective sections again:

"Kovatsch  Matthias" <[email-masked]> writes:

> 1. Message Processing
> Which approach did you choose and why, on-the-fly processing (keeping
> header fields and options encoded in local memory) or internal data
> structure (a native struct/object that is serialized on send)? It
> would be important to add the context of your implementation and
> decision: is it optimized for memory size, throughput, or usability?

CoAP messages are processed on-the-fly to reduce the memory overhead. It
has turned out that this works good for real-world applications on
constrained devices, but imposes some burden on the application
developer because he must be ensure that options (and data) are added in
correct order to avoid memmoves. Processing of block options hence goes
into the application code as well.

> 2. Duplicate Rejection
> Have you implemented full duplicate rejection with timers? Or do you
> rely on idempotency and application-specific handling of duplicates?

libcoap does no duplicate rejection to avoid keeping additional
state. For resources, where this is required, the detection could be
implemented in the application code.

> 3. Token Usage
> There has been continuous confusion about token usage on the mailing
> list and during interop events (e.g., in combination with blockwise
> transfers). Is there something you consider underspecified in RFC7252
> or hard to get right (e.g., coping with reboots)?

No, I think the token usage is clearly defined. (With libcoap, the
application designer has to define which token to use, so he must be
careful to generate new tokens at reboot.)

> 4. Programming Model
> Did you use a model for embedded implementations that is not
> event-driven? Which is it and why did you choose it?

libcoap follows an event-driven model with callbacks.

> requirements useful to you?

Yes, at least for naming these different types.

> Do you have further optimizations that you want to share?

I would change the last two sentences of the second paragraph in
Section 3.1.:

OLD:
   This does not work for Confirmable
   messages, however.  They need to be stored for retransmission and
   would block any further IP communication.

NEW:
   This does not work for Confirmable
   messages as these must be kept for retransmission until an
   Ack message is received. As the IP buffer must be available
   to store received packets, a separate buffer is required to
   hold the Confirmable message. 

The third paragraph is about separate responses? The reader must have a
very clear picture of the intended implementation to understand the
text. (The text also reads as if Token still was an option.) Maybe
making the idea more explicit might help:

OLD:

   Depending on the number of requests that can be handled in parallel,
   an implementation might create a stub response filled with any option
   that has to be copied from the original request to the separate
   response, especially the Token option.  The drawback of this
   technique is that the server must be prepared to receive
   retransmissions of the previous (Confirmable) request to which a new
   acknowledgement must be generated.  If memory is an issue, a single
   buffer can be used for both tasks: Only the message type and code
   must be updated, changing the message id is optional.  Once the
   resource representation is known, it is added as new payload at the
   end of the stub response.  Acknowledgements still can be sent as
   described before as long as no additional options are required to
   describe the payload.

NEW:

   Buffer usage for separate responses can be optimized by creating a
   stub response after the Empty Acknowledgement message was sent. The
   stub response is filled with the Token and any option that must be
   copied from the original request to the separate response.

   The drawback of this technique is that the server must be prepared to
   receive retransmissions of the previous (Confirmable) request to
   which a new acknowledgement must be generated. If memory is an issue,
   a single buffer can be used for both, the Empty Acknowledgement and
   the stub response. After sending the Acknowledgement, the basic
   message header must be updated to reflect the type, code and Token
   Length for the prepared response. Changing the message id is optional.

   Once the resource representation is known, it is added as new payload
   at the end of the stub response.  Acknowledgements still can be sent
   as described before as long as no additional options are required to
   describe the payload.

Section 3.2 refers to Section 2.6 for eventual consistency of
Confirmable notifications. Section 2.6 deals with Out-of-band
information, especially ICMP. I do not see the relevance of this
reference.

The last paragraph of Section 3.2. suggests a two-step strategy for
retransmissions that enables longer sleep cycles. Maybe it is worth
mentioning that this works only if the device wakes up when a new
network packet has arrived. Otherwise, the Acknowledgement would get
lost. (The device could just ignore this fact, but this would contribute
to network congestion.)

Section 3.5. (Deduplication with Sequential MIDs) refers to 'RFC 7252,
section "reliable messages"' which does not exists. I think this should
be

OLD:

  ([RFC7252] section "Reliable Messages")

NEW:

  ([RFC7252] Section 4.2)

The last sentence of the first paragraph in Section 3.5 is a bit
misleading. While a client that receives a duplicate a response to a
(retransmitted) confirmable request could silently discard it, a server
that receives a duplicate of a request must first send the
Acknowledgement (and possibly the response in case it is already known)
and then discard the incoming request (instead of delivering it to the
application layer). For Non-confirmable messages, I read Section 4.5 of
RFC 7252 indeed that duplicates are silently discarded.

In the paragraph below Table 1:

OLD:

  k=64

NEW:

  K=64

"to store in best case up to 130 MID values using 20 bytes": This does
not include the storage space used for the time value, which will add
another system-dependent number of bytes (typically 2, 4 or 8 per
timestamp), making the difference between sequential and non-sequential
case even larger.

> Did you tweak any of the transmission parameters in your

No, but there has been a request for this in the past (for reasearch
purposes, AFAIK).

> Do you use IPv4 and did you run into problems when deploying your

IPv4 is supported by libcoap but no experience has been reported so far
about its behavior in a NATed environment. The only deployments in a
NATed network I know of use a CoAP server residing on the NAT itself,
providing both, an internal and an external transport interface.

Best regards
Olaf

---

From: Carsten Bormann <[email-masked]>
Date: Wed, 22 Apr 2015 11:45:59 +0200

>    hold the Confirmable message. 

(Another approach is to completely re-generate the message from scratch
for each retransmission.)

Grüße, Carsten