idnits 2.17.1 draft-ietf-lwig-coap-01.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (July 04, 2014) is 3583 days in the past. Is this intentional? Checking references for intended status: Informational ---------------------------------------------------------------------------- == Outdated reference: A later version (-04) exists of draft-bormann-core-cocoa-02 == Outdated reference: A later version (-21) exists of draft-ietf-core-block-14 == Outdated reference: A later version (-16) exists of draft-ietf-core-observe-14 ** Obsolete normative reference: RFC 7230 (Obsoleted by RFC 9110, RFC 9112) Summary: 1 error (**), 0 flaws (~~), 4 warnings (==), 1 comment (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 LWIG Working Group M. Kovatsch 3 Internet-Draft ETH Zurich 4 Intended status: Informational O. Bergmann 5 Expires: January 5, 2015 Universitaet Bremen TZI 6 E. Dijk 7 Philips Research 8 X. He 9 Hitachi (China) R&D Corp. 10 C. Bormann, Ed. 11 Universitaet Bremen TZI 12 July 04, 2014 14 CoAP Implementation Guidance 15 draft-ietf-lwig-coap-01 17 Abstract 19 The Constrained Application Protocol (CoAP) is designed for resource- 20 constrained nodes and networks, e.g., sensor nodes in a low-power 21 lossy network (LLN). Yet to implement this Internet protocol on 22 Class 1 devices (as per RFC 7228, ~ 10 KiB of RAM and ~ 100 KiB of 23 ROM) also lightweight implementation techniques are necessary. This 24 document provides lessons learned from implementing CoAP for tiny, 25 battery-operated networked embedded systems. In particular, it 26 provides guidance on correct implementation of the CoAP specification 27 RFC 7252, memory optimizations, and customized protocol parameters. 29 Status of This Memo 31 This Internet-Draft is submitted in full conformance with the 32 provisions of BCP 78 and BCP 79. 34 Internet-Drafts are working documents of the Internet Engineering 35 Task Force (IETF). Note that other groups may also distribute 36 working documents as Internet-Drafts. The list of current Internet- 37 Drafts is at http://datatracker.ietf.org/drafts/current/. 39 Internet-Drafts are draft documents valid for a maximum of six months 40 and may be updated, replaced, or obsoleted by other documents at any 41 time. It is inappropriate to use Internet-Drafts as reference 42 material or to cite them other than as "work in progress." 44 This Internet-Draft will expire on January 5, 2015. 46 Copyright Notice 48 Copyright (c) 2014 IETF Trust and the persons identified as the 49 document authors. All rights reserved. 51 This document is subject to BCP 78 and the IETF Trust's Legal 52 Provisions Relating to IETF Documents 53 (http://trustee.ietf.org/license-info) in effect on the date of 54 publication of this document. Please review these documents 55 carefully, as they describe your rights and restrictions with respect 56 to this document. Code Components extracted from this document must 57 include Simplified BSD License text as described in Section 4.e of 58 the Trust Legal Provisions and are provided without warranty as 59 described in the Simplified BSD License. 61 Table of Contents 63 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 64 2. Protocol Implementation . . . . . . . . . . . . . . . . . . . 4 65 2.1. Client/Server Model . . . . . . . . . . . . . . . . . . . 4 66 2.2. Message Processing . . . . . . . . . . . . . . . . . . . 5 67 2.2.1. On-the-fly Processing . . . . . . . . . . . . . . . . 5 68 2.2.2. Internal Data Structure . . . . . . . . . . . . . . . 6 69 2.3. Duplicate Rejection . . . . . . . . . . . . . . . . . . . 6 70 2.4. Token Usage . . . . . . . . . . . . . . . . . . . . . . . 7 71 2.4.1. Tokens for Observe . . . . . . . . . . . . . . . . . 7 72 2.4.2. Tokens for Blockwise Transfers . . . . . . . . . . . 8 73 2.5. Transmission States . . . . . . . . . . . . . . . . . . . 8 74 2.5.1. Request/Response Layer . . . . . . . . . . . . . . . 9 75 2.5.2. Message Layer . . . . . . . . . . . . . . . . . . . . 10 76 2.6. Out-of-band Information . . . . . . . . . . . . . . . . . 11 77 2.7. Programming Model . . . . . . . . . . . . . . . . . . . . 11 78 2.7.1. Client . . . . . . . . . . . . . . . . . . . . . . . 12 79 2.7.2. Server . . . . . . . . . . . . . . . . . . . . . . . 12 80 3. Optimizations . . . . . . . . . . . . . . . . . . . . . . . . 13 81 3.1. Message Buffers . . . . . . . . . . . . . . . . . . . . . 13 82 3.2. Retransmissions . . . . . . . . . . . . . . . . . . . . . 14 83 3.3. Observable Resources . . . . . . . . . . . . . . . . . . 14 84 3.4. Blockwise Transfers . . . . . . . . . . . . . . . . . . . 15 85 3.5. Deduplication with Sequential MIDs . . . . . . . . . . . 15 86 4. Alternative Configurations . . . . . . . . . . . . . . . . . 18 87 4.1. Transmission Parameters . . . . . . . . . . . . . . . . . 18 88 4.2. CoAP over IPv4 . . . . . . . . . . . . . . . . . . . . . 19 89 5. IANA considerations . . . . . . . . . . . . . . . . . . . . . 19 90 6. Security considerations . . . . . . . . . . . . . . . . . . . 19 91 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 19 92 7.1. Normative References . . . . . . . . . . . . . . . . . . 19 93 7.2. Informative References . . . . . . . . . . . . . . . . . 20 95 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 20 97 1. Introduction 99 The Constrained Application Protocol [RFC7252] has been designed 100 specifically for machine-to-machine communication in networks with 101 very constrained nodes. Typical application scenarios therefore 102 include building automation, process optimization, and the Internet 103 of Things. The major design objectives have been set on small 104 protocol overhead, robustness against packet loss, and against high 105 latency induced by small bandwidth shares or slow request processing 106 in end nodes. To leverage integration of constrained nodes with the 107 world-wide Internet, the protocol design was led by the REST 108 architectural style that accounts for the scalability and robustness 109 of the Hypertext Transfer Protocol [RFC7230]. 111 Lightweight implementations benefit from this design in many 112 respects: First, the use of Uniform Resource Identifiers (URIs) for 113 naming resources and the transparent forwarding of their 114 representations in a server-stateless request/response protocol make 115 protocol translation to HTTP a straightforward task. Second, the set 116 of protocol elements that are unavoidable for the core protocol and 117 thus must be implemented on every node has been kept very small, 118 minimizing the unnecessary accumulation of "optional" features. 119 Options that - when present - are critical for message processing are 120 explicitly marked as such to force immediate rejection of messages 121 with unknown critical options. Third, the syntax of protocol data 122 units is easy to parse and is carefully defined to avoid creation of 123 state in servers where possible. 125 Although these features enable lightweight implementations of the 126 Constrained Application Protocol, there is still a tradeoff between 127 robustness and latency of constrained nodes on one hand and resource 128 demands on the other. For constrained nodes of Class 1 or even 129 Class 2 [RFC7228], the most limiting factors usually are dynamic 130 memory needs, static code size, and energy. Most implementations 131 therefore need to optimize internal buffer usage, omit idle protocol 132 feature, and maximize sleeping cycles. 134 The present document gives possible strategies to solve this tradeoff 135 for very constrained nodes (i.e., Class 1). For this, it provides 136 guidance on correct implementation of the CoAP specification 137 [RFC7252], memory optimizations, and customized protocol parameters. 139 2. Protocol Implementation 141 In the programming styles supported by very simple operating systems 142 as found on constrained nodes, preemptive multi-threading is not an 143 option. Instead, all operations are triggered by an event loop 144 system, e.g., in a send-receive-dispatch cycle. It is also common 145 practice to allocate memory statically to ensure stable behavior, as 146 no memory management unit (MMU) or other abstractions are available. 147 For a CoAP node, the two key parameters for memory usage are the 148 number of (re)transmission buffers and the maximum message size that 149 must be supported by each buffer. Often the maximum message size is 150 set far below the 1280-byte MTU of 6LoWPAN to allow more than one 151 open Confirmable transmission at a time (in particular for parallel 152 observe notifications [I-D.ietf-core-observe]). Note that 153 implementations on constrained platforms often not even support the 154 full MTU. Larger messages must then use blockwise transfers 155 [I-D.ietf-core-block], while a good tradeoff between 6LoWPAN 156 fragmentation and CoAP header overhead must be found. Usually the 157 amount of available free RAM dominates this decision. For Class 1 158 devices, the maximum message size is typically 128 or 256 bytes 159 (blockwise) payload plus an estimate of the maximum header size with 160 a worst case option setting. 162 2.1. Client/Server Model 164 In general, CoAP servers can be implemented more efficiently than 165 clients. REST allows them to keep the communication stateless and 166 piggy-backed responses are not stored for retransmission, saving 167 buffer space. The use of idempotent requests also allows to relax 168 deduplication, which further decreases memory usage. It is also easy 169 to estimate the required maximum size of message buffers, since URI 170 paths, supported options, and maximum payload sizes of the 171 application are known at compile time. Hence, when the application 172 is distributed over constrained and unconstrained nodes, the 173 constrained ones should preferably have the server role. 175 HTTP-based applications have established an inverse model because of 176 the need for simple push notifications: A constrained client uses 177 POST requests to update resources on an unconstrained server whenever 178 an event, e.g., a new sensor reading, is triggered. This requirement 179 is solved by the Observe option [I-D.ietf-core-observe] of CoAP. It 180 allows servers to initiate communication and send push notifications 181 to interested client nodes. This allows a more efficient and also 182 more natural model for CoAP-based applications, where the information 183 source is in server role and can benefit from caching. 185 2.2. Message Processing 187 Apart from the required buffers, message processing is symmetric for 188 clients and servers. First the 4-byte base header has to be parsed 189 and thereby checked if it is a CoAP message. Since the encoding is 190 very dense, only a wrong Version or a datagram size smaller than four 191 bytes identify non-CoAP datagrams. These need to be silently 192 ignored. Other message format errors, such as an incomplete datagram 193 length or the usage of reserved values, may need to be rejected with 194 a Reset (RST) message (see Section 4.2 and 4.3 of [RFC7252] for 195 details). Next the Token is read based on the TKL field. For the 196 following header options, there are two alternatives: Either process 197 the header on the fly when an option is accessed or initially parse 198 all values into an internal data structure. 200 2.2.1. On-the-fly Processing 202 The advantage of on-the-fly processing is that no additional memory 203 needs to be allocated to store the option values, which are stored 204 efficiently inline in the buffer for incoming messages. Once the 205 message is accepted for further processing, the set of options 206 contained in the received message must be decoded to check for 207 unknown critical options. To avoid multiple passes through the 208 option list, the option parser might maintain a bit-vector where each 209 bit represents an option number that is present in the received 210 request. With the wide and sparse range of option numbers, the 211 number itself cannot be used to indicate the number of left-shift 212 operations to mask the corresponding bit. Hence, an implementation- 213 specific enum of supported options should be used to mask the present 214 options of a message in the bitmap. In addition, the byte index of 215 every option (a direct pointer) can be added to a sparse list (e.g., 216 a one-dimensional array) for fast retrieval. 218 This particularly enables efficient handling of options that might 219 occur more than once such as Uri-Path. In this implementation 220 strategy, the delta is zero for any subsequent path segment, hence 221 the stored byte index for this option (e.g., 11 for Uri-Path) would 222 be overwritten to hold a pointer to only the last occurrence of that 223 option. The Uri-Path can be resolved on the fly, though, and a 224 pointer to the targeted resource stored directly in the sparse list. 225 In simpler cases, conditionals can preselect one of the repeated 226 option values. 228 Once the option list has been processed, all known critical option 229 and all elective options can be masked out in the bit-vector to 230 determine if any unknown critical option was present. If this is the 231 case, this information can be used to create a 4.02 response 232 accordingly. Note that full processing must only be done up to the 233 highest supported option number. Beyond that, only the least 234 significant bit (Critical or Elective) needs to be checked. 235 Otherwise, if all critical options are supported, the sparse list of 236 option pointers is used for further handling of the message. 238 2.2.2. Internal Data Structure 240 Using an internal data structure for all parsed options has an 241 advantage when working on the option values, as they are already in a 242 variable of corresponding type, e.g., an integer in host byte order. 243 The incoming payload and byte strings of the header can be accessed 244 directly in the buffer for incoming messages using pointers (similar 245 to on-the-fly processing). This approach also benefits from a 246 bitmap. Otherwise special values must be reserved to encode an unset 247 option, which might require a larger type than required for the 248 actual value range (e.g., a 32-bit integer instead of 16-bit). 250 The byte strings (e.g., the URI) are usually not required when 251 generating the response. And since all important values were copied, 252 this alternative facilitates using the buffer for incoming messages 253 also for the assembly of outgoing messages - which can be the shared 254 IP buffer provided by the OS. 256 Setting options for outgoing messages is also easier with an internal 257 data structure. Application developers can set options independent 258 from the option number, whose order is required for the delta 259 encoding. The CoAP encoding is then applied in a serialization step 260 before sending. In contrast, assembling outgoing messages with on- 261 the-fly processing requires either extensive memmove operations to 262 insert new header options or restrictions for developers to set 263 options in their correct order. 265 2.3. Duplicate Rejection 267 If CoAP is used directly on top of UDP (i.e., in NoSec mode), it 268 needs to cope with the fact that the UDP datagram transport can 269 reorder and duplicate messages. (In contrast to UDP, DTLS has its 270 own duplicate detection.) CoAP has been designed with protocol 271 functionality such that rejection of duplicate messages is always 272 possible. It is at the discretion of the receiver if it actually 273 wants to make use of this functionality. Processing of duplicate 274 messages comes at a cost, but so does the management of the state 275 associated with duplicate rejection. The number of remote endpoints 276 that need to be managed might be vast. This can be costly in 277 particular for unconstrained nodes that have throughput in the order 278 of one hundred thousand requests per second (which might need about 279 16 GiB of RAM just for duplicate rejection). Deduplication is also 280 heavy for servers on Class 1 devices, as also piggy-backed responses 281 need to be stored for the case that the ACK message is lost. Hence, 282 a receiver may have good reasons to decide not to do the 283 deduplication. 285 If duplicate rejection is indeed necessary, e.g., for non-idempotent 286 requests, it is important to control the amount of state that needs 287 to be stored. It can be reduced for instance by deduplication at 288 resource level: Knowledge of the application and supported 289 representations can minimize the amount of state that needs to be 290 kept. Duplicate rejection on the client side can be simplified by 291 choosing clever Tokens and only filter based on this information 292 (e.g., a list of Tokens currently in use or an obscured counter in 293 the Token value). 295 2.4. Token Usage 297 Tokens are chosen by the client and help to identify request/response 298 pairs that span several message exchanges (e.g., a separate response, 299 which has a new MID). Servers do not generate Tokens and only mirror 300 what they receive from the clients. Tokens must be unique within the 301 namespace of a client throughout their lifetime. This begins when 302 being assigned to a request and ends when the open request is closed 303 by receiving and matching the final response. Neither empty ACKs nor 304 notifications (i.e., responses carrying the Observe option) terminate 305 the lifetime of a Token. 307 As already mentioned, a clever assignment of Tokens can help to 308 simplify duplicate rejection. Yet this is also important for coping 309 with client crashes. When a client restarts during an open request 310 and (unknowingly) re-uses the same Token, it might match the response 311 from the previous request to the current one. Hence, when only the 312 Token is used for matching, which is always the case for separate 313 responses, randomized Tokens with enough entropy should be used. The 314 8-byte range for Tokens even allows for one-time usage throughout the 315 lifetime of a client node. When DTLS is used, client crashes/ 316 restarts will lead to a new security handshake, thereby solving the 317 problem of mismatching responses and/or notifications. 319 2.4.1. Tokens for Observe 321 In the case of Observe [I-D.ietf-core-observe], a request will be 322 answered with multiple notifications and it can become hard to 323 determine the end of a Token lifetime. When establishing an Observe 324 relationship, the Token is registered at the server. Hence, the 325 client partially loses control of the used Token. A client can 326 attempt to cancel the relationship, which frees the Token upon 327 success (i.e., the message with an Observe Option with the value set 328 to 'deregister' (1) is acknowledged; see [I-D.ietf-core-observe] 329 section 3.6). However, the client might never receive the ACK due to 330 a temporary network outages or worse, a server crash. Although a 331 network outage will also affect notifications so that the Observe 332 garbage collection could apply, the server might simply not send CON 333 notifications during that time. Alternative Observe lifetime models 334 such as Stubbornness(tm) might also keep relationships alive for 335 longer periods. 337 Thus, Observe requests should carefully chose the value (and the 338 empty value will rarely be applicable). One option is to assign and 339 re-use dedicated Tokens for each Observe relationship the client will 340 establish. This is, however, critical for spoofing attacks in NoSec 341 mode. The recommendation is to use randomized Tokens with a length 342 of at least four bytes (see Section 5.3.1 of [RFC7252]). Thus, 343 dedicated ranges within the 8-byte Token space should be used when in 344 NoSec mode. This also solves the problem of mismatching 345 notifications after a client crash/restart. 347 2.4.2. Tokens for Blockwise Transfers 349 In general, blockwise transfers are independent from the Token and 350 are correlated through client endpoint address and server address and 351 resource path (destination URI). Thus, each block may be transferred 352 using a different Token. Still it can be beneficial to use the same 353 Token (it is freed upon reception of a response block) for all 354 blocks, e.g., to easily route received blocks to the same response 355 handler. 357 When Block2 is combined with Observe, notifications only carry the 358 first block and it is up to the client to retrieve the remaining 359 ones. These GET requests do not carry the Observe option and need to 360 use a different Token, since the Token from the notification is still 361 in use. 363 2.5. Transmission States 365 CoAP endpoints must keep transmission state to manage open requests, 366 to handle the different response modes, and to implement reliable 367 delivery at the message layer. The following finite state machines 368 (FSMs) model the transmissions of a CoAP exchange at the request/ 369 response layer and the message layer. These layers are linked 370 through actions. The M_CMD() action triggers a corresponding 371 transition at the message layer and the RR_EVT() action triggers a 372 transition at the request/response layer. The FSMs also use guard 373 conditions to distinguish between information that is only available 374 through the other layer (e.g., whether a request was sent using a CON 375 or NON message). 377 2.5.1. Request/Response Layer 379 Figure 1 depicts the two states at the request/response layer of a 380 CoAP client. When a request is issued, a "reliable_send" or 381 "unreliable_send" is triggered at the message layer. The WAITING 382 state can be left through three transitions: Either the client 383 cancels the request and triggers cancellation of a CON transmission 384 at the message layer, the client receives a failure event from the 385 message layer, or a receive event containing a response. 387 +------------CANCEL-------------------------------+ 388 | / M_CMD(cancel) | 389 | V 390 | +------+ 391 +-------+ -------RR_EVT(fail)--------------------> | | 392 |WAITING| | IDLE | 393 +-------+ -------RR_EVT(rx)[is Response]---------> | | 394 ^ / M_CMD(accept) +------+ 395 | | 396 +--------------------REQUEST----------------------+ 397 / M_CMD((un)reliable_send) 399 Figure 1: CoAP Client Request/Response Layer FSM 401 A server resource can decide at the request/response layer whether to 402 respond with a piggy-backed or a separate response. Thus, there are 403 two busy states in Figure 2, SERVING and SEPARATE. An incoming 404 receive event with a NON request directly triggers the transition to 405 the SEPARATE state. 407 +--------+ <----------RR_EVT(rx)[is NON]---------- +------+ 408 |SEPARATE| | | 409 +--------+ ----------------RESPONSE--------------> | IDLE | 410 ^ / M_CMD((un)reliable_send) | | 411 | +---> +------+ 412 |EMPTY_ACK | | 413 |/M_CMD(accept) | | 414 | | | 415 | | | 416 +--------+ | | 417 |SERVING | --------------RESPONSE------------+ | 418 +--------+ / M_CMD(accept) | 419 ^ | 420 +------------------------RR_EVT(rx)[is CON]--------+ 422 Figure 2: CoAP Server Request/Response Layer FSM 424 2.5.2. Message Layer 426 Figure 3 shows the different states of a CoAP endpoint per message 427 exchange. Besides the linking action RR_EVT(), the message layer has 428 a TX action to send a message. For sending and receiving NONs, the 429 endpoint remains in its CLOSED state. When sending a CON, the 430 endpoint remains in RELIABLE_TX and keeps retransmitting until the 431 transmission times out, it receives a matching RST, the request/ 432 response layer cancels the transmission, or the endpoint receives an 433 implicit acknowledgement through a matching NON or CON. Whenever the 434 endpoint receives a CON, it transitions into the ACK_PENDING state, 435 which can be left by sending the corresponding ACK. 437 +-----------+ <-------M_CMD(reliable_send)-----+ 438 | | / TX(con) \ 439 | | +--------------+ 440 | | ---TIMEOUT(RETX_WINDOW)------> | | 441 |RELIABLE_TX| / RR_EVT(fail) | | 442 | | ---------------------RX_RST--> | | <----+ 443 | | / RR_EVT(fail) | | | 444 +-----------+ ----M_CMD(cancel)------------> | CLOSED | | 445 ^ | | \ \ | | --+ | 446 | | | \ +-------------------RX_ACK---> | | | | 447 +*1+ | \ / RR_EVT(rx) | | | | 448 | +----RX_NON-------------------> +--------------+ | | 449 | / RR_EVT(rx) ^ ^ ^ ^ | | | | | | 450 | | | | | | | | | | | 451 | | | | +*2+ | | | | | 452 | | | +--*3--+ | | | | 453 | | +----*4----+ | | | 454 | +------*5------+ | | 455 | +---------------+ | | 456 | | ACK_PENDING | <--RX_CON-------------+ | 457 +----RX_CON----> | | / RR_EVT(rx) | 458 / RR_EVT(rx) +---------------+ ---------M_CMD(accept)---+ 459 / TX(ack) 461 *1: TIMEOUT(RETX_TIMEOUT) / TX(con) 462 *2: M_CMD(unreliable_send) / TX(non) 463 *3: RX_NON / RR_EVT(rx) 464 *4: RX_RST / REMOVE_OBSERVER 465 *5: RX_ACK 467 Figure 3: CoAP Message Layer FSM 469 T.B.D.: (i) Rejecting messages (can be triggered at message and 470 request/response layer). (ii) ACKs can also be triggered at both 471 layers. 473 2.6. Out-of-band Information 475 The CoAP implementation can also leverage out-of-band information, 476 that might also trigger some of the transitions shown in Section 2.5. 477 In particular ICMP messages can inform about unreachable remote 478 endpoints or whole network outages. This information can be used to 479 pause or cancel ongoing transmission to conserve energy. Providing 480 ICMP information to the CoAP implementation is easier in constrained 481 environments, where developers usually can adapt the underlying OS 482 (or firmware). This is not the case on general purpose platforms 483 that have full-fledged OSes and make use of high-level programming 484 frameworks. 486 The most important ICMP messages are host, network, port, or protocol 487 unreachable errors. After appropriate vetting (cf. [RFC5927]), they 488 should cause the cancellation of ongoing CON transmissions and 489 clearing (or deferral) of Observe relationships. Requests to this 490 destination should be paused for a sensible interval. In addition, 491 the device could indicate of this error through a notification to a 492 management endpoint or external status indicator, since the cause 493 could be a misconfiguration or general unavailability of the required 494 service. Problems reported through the Parameter Problem message are 495 usually caused through a similar fundamental problem. 497 The CoAP specification recommends to ignore Source Quench and Time 498 Exceeded ICMP messages, though. Source Quench messages were 499 originally intended to inform the sender to reduce the rate of 500 packets. However, this mechanism is deprecated through [RFC6633]. 501 CoAP also comes with its own congestion control mechanism, which is 502 already designed conservatively. One advanced mechanism that can be 503 employed for better network utilization is CoCoA, 504 [I-D.bormann-core-cocoa]. Time Exceeded messages often occur during 505 transient routing loops (unless they are caused by a too small 506 initial Hop Limit value). 508 2.7. Programming Model 510 The event-driven approach, which is common in event-loop-based 511 firmware, has also proven very efficient for embedded operating 512 systems [TinyOS], [Contiki]. Note that an OS is not necessarily 513 required and a traditional firmware approach can suffice for Class 1 514 devices. Event-driven systems use split-phase operations (i.e., 515 there are no blocking functions, but functions return and an event 516 handler is called once a long-lasting operation completes) to enable 517 cooperative multi-threading with a single stack. 519 Bringing a Web transfer protocol to constrained environments does not 520 only change the networking of the corresponding systems, but also the 521 programming model. The complexity of event-driven systems can be 522 hidden through APIs that resemble classic RESTful Web service 523 implementations. 525 2.7.1. Client 527 An API for asynchronous requests with response handler functions goes 528 hand-in-hand with the event-driven approach. Synchronous requests 529 with a blocking send function can facilitate applications that 530 require strictly ordered, sequential request execution (e.g., to 531 control a physical process) or other checkpointing (e.g., starting 532 operation only after registration with the resource directory was 533 successful). However, this can also be solved by triggering the next 534 operation in the response handlers. Furthermore, as mentioned in 535 Section 2.1, it is more like that complex control flow is done by 536 more powerful devices and Class 1 devices predominantly run a CoAP 537 server (which might include a minimal client to communicate with a 538 resource directory). 540 2.7.2. Server 542 On CoAP servers, the event-driven nature can be hidden through 543 resource handler abstractions as known from traditional REST 544 frameworks. The following types of RESTful resources have proven 545 useful to provide an intuitive API on constrained event-driven 546 systems: 548 NORMAL A normal resource defined by a static Uri-Path and an 549 associated resource handler function. Allowed methods could 550 already be filtered by the implementation based on flags. This is 551 the basis for all other resource types. 553 PARENT A parent resource manages several sub-resources under a given 554 base path by programmatically evaluating the Uri-Path. Defining a 555 URI template (see [RFC6570]) would be a convenient way to pre- 556 parse arguments given in the Uri-Path. 558 PERIODIC A resource that has an additional handler function that is 559 triggered periodically by the CoAP implementation with a resource- 560 specific interval. It can be used to sample a sensor or perform 561 similar periodic updates of its state. Usually, a periodic 562 resource is observable and sends the notifications by triggering 563 its normal resource handler from the periodic handler. These 564 periodic tasks are quite common for sensor nodes, thus it makes 565 sense to provide this functionality in the CoAP implementation and 566 avoid redundant code in every resource. 568 EVENT An event resource is similar to an periodic resource, only 569 that the second handler is called by an irregular event such as a 570 button. 572 SEPARATE Separate responses are usually used when handling a request 573 takes more time, e.g., due to a slow sensor or UART-based 574 subsystems. To not fully block the system during this time, the 575 handler should also employ split-phase execution: The resource 576 handler returns as soon as possible and an event handler resumes 577 responding when the result is ready. The separate resource type 578 can abstract from the split-phase operation and take care of 579 temporarily storing the request information that is required later 580 in the result handler to send the response (e.g., source address 581 and Token). 583 3. Optimizations 585 3.1. Message Buffers 587 The cooperative multi-threading of an event loop system allows to 588 optimize memory usage through in-place processing and reuse of 589 buffers, in particular the IP buffer provided by the OS or firmware. 591 CoAP servers can significantly benefit from in-place processing, as 592 they can create responses directly in the incoming IP buffer. Note 593 that an embedded OS usually only has a single buffer for incoming and 594 outgoing IP packets. The first few bytes of the basic header are 595 usually parsed into an internal data structure and can be overwritten 596 without harm. Thus, empty ACKs and RST messages can promptly be 597 assembled and sent using the IP buffer. Also when a CoAP server only 598 sends piggy-backed or Non-confirmable responses, no additional buffer 599 is required at the application layer. This, however, requires 600 careful timing so that no incoming data is overwritten before it was 601 processed. Because of cooperative multi-threading, this requirement 602 is relaxed, though. Once the message is sent, the IP buffer can 603 accept new messages again. This does not work for Confirmable 604 messages, however. They need to be stored for retransmission and 605 would block any further IP communication. 607 Depending on the number of requests that can be handled in parallel, 608 an implementation might create a stub response filled with any option 609 that has to be copied from the original request to the separate 610 response, especially the Token option. The drawback of this 611 technique is that the server must be prepared to receive 612 retransmissions of the previous (Confirmable) request to which a new 613 acknowledgement must be generated. If memory is an issue, a single 614 buffer can be used for both tasks: Only the message type and code 615 must be updated, changing the message id is optional. Once the 616 resource representation is known, it is added as new payload at the 617 end of the stub response. Acknowledgements still can be sent as 618 described before as long as no additional options are required to 619 describe the payload. 621 3.2. Retransmissions 623 CoAP's reliable transmissions require the before-mentioned 624 retransmission buffers. Messages, such as the requests of a client, 625 should be stored in serialized form. For servers, retransmissions 626 apply for Confirmable separate responses and Confirmable 627 notifications [I-D.ietf-core-observe]. As separate responses stem 628 from long-lasting resource handlers, the response should be stored 629 for retransmission instead of re-dispatching a stored request (which 630 would allow for updating the representation). For Confirmable 631 notifications, please see Section 2.6, as simply storing the response 632 can break the concept of eventual consistency. 634 String payloads such as JSON require a buffer to print to. By 635 splitting the retransmission buffer into header and payload part, it 636 can be reused. First to generate the payload and then storing the 637 CoAP message by serializing into the same memory. Thus, providing a 638 retransmission for any message type can save the need for a separate 639 application buffer. This, however, requires an estimation about the 640 maximum expected header size to split the buffer and a memmove to 641 concatenate the two parts. 643 For platforms that disable clock tick interrupts in sleep states, the 644 application must take into consideration the clock deviation that 645 occurs during sleep (or ensure to remain in idle state until the 646 message has been acknowledged or the maximum number of 647 retransmissions is reached). Since CoAP allows up to four 648 retransmissions with a binary exponential back-off it could take up 649 to 45 seconds until the send operation is complete. Even in idle 650 state, this means substantial energy consumption for low-power nodes. 651 Implementers therefore might choose a two-step strategy: First, do 652 one or two retransmissions and then, in the later phases of back-off, 653 go to sleep until the next retransmission is due. In the meantime, 654 the node could check for new messages including the acknowledgement 655 for any Confirmable message to send. 657 3.3. Observable Resources 659 For each observer, the server needs to store at least address, port, 660 token, and the last outgoing message ID. The latter is needed to 661 match incoming RST messages and cancel the observe relationship. 663 It is favorable to have one retransmission buffer per observable 664 resource that is shared among all observers. Each notification is 665 serialized once into this buffer and only address, port, and token 666 are changed when iterating over the observer list (note that 667 different token lengths might require realignment). The advantage 668 becomes clear for Confirmable notifications: Instead of one 669 retransmission buffer per observer, only one buffer and only 670 individual retransmission counters and timers in the list entry need 671 to be stored. When the notifications can be sent fast enough, even a 672 single timer would suffice. Furthermore, per-resource buffers 673 simplify the update with a new resource state during open deliveries. 675 3.4. Blockwise Transfers 677 Blockwise transfers have the main purpose of providing fragmentation 678 at the application layer, where partial information can be processed. 679 This is not possible at lower layers such as 6LoWPAN, as only 680 assembled packets can be passed up the stack. While 681 [I-D.ietf-core-block] also anticipates atomic handling of blocks, 682 i.e., only fully received CoAP messages, this is not possible on 683 Class 1 devices. 685 When receiving a blockwise transfer, each block is usually passed to 686 a handler function that for instance performs stream processing or 687 writes the blocks to external memory such as flash. Although there 688 are no restrictions in [I-D.ietf-core-block], it is beneficial for 689 Class 1 devices to only allow ordered transmission of blocks. 690 Otherwise on-the-fly processing would not be possible. 692 When sending a blockwise transfer out of dynamically generated 693 information, Class 1 devices usually do not have sufficient memory to 694 print the full message into a buffer, and slice and send it in a 695 second step. For instance, if the CoRE Link Format at /.well-known/ 696 core is dynamically generated, a generator function is required that 697 generates slices of a large string with a specific offset length (a 698 'sonprintf()'). This functionality is required recurrently and 699 should be included in a library. 701 3.5. Deduplication with Sequential MIDs 703 CoAP's duplicate rejection functionality can be straightforwardly 704 implemented in a CoAP endpoint by storing, for each remote CoAP 705 endpoint ("peer") that it communicates with, a list of recently 706 received CoAP Message IDs (MIDs) along with some timing information. 707 A CoAP message from a peer with a MID that is in the list for that 708 peer can simply be discarded. 710 The timing information in the list can then be used to time out 711 entries that are older than the _expected extent of the re-ordering_, 712 an upper bound for which can be estimated by adding the _potential 713 retransmission window_ ([RFC7252] section "Reliable Messages") and 714 the time packets can stay alive in the network. 716 Such a straightforward implementation is suitable in case other CoAP 717 endpoints generate random MIDs. However, this storage method may 718 consume substantial RAM in specific cases, such as: 720 o many clients are making periodic, non-idempotent requests to a 721 single CoAP server; 723 o one client makes periodic requests to a large number of CoAP 724 servers and/or requests a large number of resources; where servers 725 happen to mostly generate separate CoAP responses (not piggy- 726 backed); 728 For example, consider the first case where the expected extent of re- 729 ordering is 50 seconds, and N clients are sending periodic POST 730 requests to a single CoAP server during a period of high system 731 activity, each on average sending one client request per second. The 732 server would need 100 * N bytes of RAM to store the MIDs only. This 733 amount of RAM may be significant on a RAM-constrained platform. On a 734 number of platforms, it may be easier to allocate some extra program 735 memory (e.g. Flash or ROM) to the CoAP protocol handler process than 736 to allocate extra RAM. Therefore, one may try to reduce RAM usage of 737 a CoAP implementation at the cost of some additional program memory 738 usage and implementation complexity. 740 Some CoAP clients generate MID values by a using a Message ID 741 variable [RFC7252] that is incremented by one each time a new MID 742 needs to be generated. (After the maximum value 65535 it wraps back 743 to 0.) We call this behavior "sequential" MIDs. One approach to 744 reduce RAM use exploits the redundancy in sequential MIDs for a more 745 efficient MID storage in CoAP servers. 747 Naturally such an approach requires, in order to actually reduce RAM 748 usage in an implementation, that a large part of the peers follow the 749 sequential MID behavior. To realize this optimization, the authors 750 therefore RECOMMEND that CoAP endpoint implementers employ the 751 "sequential MID" scheme if there are no reasons to prefer another 752 scheme, such as randomly generated MID values. 754 Security considerations might call for a choice for 755 (pseudo)randomized MIDs. Note however that with truly randomly 756 generated MIDs the probability of MID collision is rather high in use 757 cases as mentioned before, following from the Birthday Paradox. For 758 example, in a sequence of 52 randomly drawn 16-bit values the 759 probability of finding at least two identical values is about 2 760 percent. 762 From here on we consider efficient storage implementations for MIDs 763 in CoAP endpoints, that are optimized to store "sequential" MIDs. 764 Because CoAP messages may be lost or arrive out-of-order, a solution 765 has to take into account that received MIDs of CoAP messages are not 766 actually arriving in a sequential fashion, due to lost or reordered 767 messages. Also a peer might reset and lose its MID counter(s) state. 768 In addition, a peer may have a single Message ID variable used in 769 messages to many CoAP endpoints it communicates with, which partly 770 breaks sequentiality from the receiving CoAP endpoint's perspective. 771 Finally, some peers might use a randomly generated MID values 772 approach. Due to these specific conditions, existing sliding window 773 bitfield implementations for storing received sequence numbers are 774 typically not directly suitable for efficiently storing MIDs. 776 Table 1 shows one example for a per-peer MID storage design: a table 777 with a bitfield of a defined length _K_ per entry to store received 778 MIDs (one per bit) that have a value in the range [MID_i + 1 , MID_i 779 + K]. 781 +----------+----------------+-----------------+ 782 | MID base | K-bit bitfield | base time value | 783 +----------+----------------+-----------------+ 784 | MID_0 | 010010101001 | t_0 | 785 | | | | 786 | MID_1 | 111101110111 | t_1 | 787 | | | | 788 | ... etc. | | | 789 +----------+----------------+-----------------+ 791 Table 1: A per-peer table for storing MIDs based on MID_i 793 The presence of a table row with base MID_i (regardless of the 794 bitfield values) indicates that a value MID_i has been received at a 795 time t_i. Subsequently, each bitfield bit k (0...K-1) in a row i 796 corresponds to a received MID value of MID_i + k + 1. If a bit k is 797 0, it means a message with corresponding MID has not yet been 798 received. A bit 1 indicates such a message has been received already 799 at approximately time t_i. This storage structure allows e.g. with 800 k=64 to store in best case up to 130 MID values using 20 bytes, as 801 opposed to 260 bytes that would be needed for a non-sequential 802 storage scheme. 804 The time values t_i are used for removing rows from the table after a 805 preset timeout period, to keep the MID store small in size and enable 806 these MIDs to be safely re-used in future communications. (Note that 807 the table only stores one time value per row, which therefore needs 808 to be updated on receipt of another MID that is stored as a single 809 bit in this row. As a consequence of only storing one time value per 810 row, older MID entries typically time out later than with a simple 811 per-MID time value storage scheme. The endpoint therefore needs to 812 ensure that this additional delay before MID entries are removed from 813 the table is much smaller than the time period after which a peer 814 starts to re-use MID values due to wrap-around of a peer's MID 815 variable. One solution is to check that a value t_i in a table row 816 is still recent enough, before using the row and updating the value 817 t_i to current time. If not recent enough, e.g. older than N 818 seconds, a new row with an empty bitfield is created.) [Clearly, 819 these optimizations would benefit if the peer were much more 820 conservative about re-using MIDs than currently required in the 821 protocol specification.] 823 The optimization described is less efficient for storing randomized 824 MIDs that a CoAP endpoint may encounter from certain peers. To solve 825 this, a storage algorithm may start in a simple MID storage mode, 826 first assuming that the peer produces non-sequential MIDs. While 827 storing MIDs, a heuristic is then applied based on monitoring some 828 "hit rate", for example, the number of MIDs received that have a Most 829 Significant Byte equal to that of the previous MID divided by the 830 total number of MIDs received. If the hit rate tends towards 1 over 831 a period of time, the MID store may decide that this particular CoAP 832 endpoint uses sequential MIDs and in response improve efficiency by 833 switching its mode to the bitfield based storage. 835 4. Alternative Configurations 837 4.1. Transmission Parameters 839 When a constrained network of CoAP nodes is not communicating over 840 the Internet, for instance because it is shielded by a proxy or a 841 closed deployment, alternative transmission parameters can be used. 842 Consequently, the derived time values provided in [RFC7252] section 843 4.8.2 will also need to be adjusted, since most implementations will 844 encode their absolute values. 846 Static adjustments require a fixed deployment with a constant number 847 or upper bound for the number of nodes, number of hops, and expected 848 concurrent transmissions. Furthermore, the stability of the wireless 849 links should be evaluated. ACK_TIMEOUT should be chosen above the 850 xx% percentile of the round-trip time distribution. 851 ACK_RANDOM_FACTOR depends on the number of nodes on the network. 852 MAX_RETRANSMIT should be chosen suitable for the targeted 853 application. A lower bound for LEISURE can be calculated as 854 lb_Leisure = S * G / R 856 where S is the estimated response size, G the group size, and R the 857 target data transfer rate (see [RFC7252] section 8.2). NSTART and 858 PROBING_RATE depend on estimated network utilization. If the main 859 cause for loss are weak links, higher values can be chosen. 861 Dynamic adjustments will be performed by advanced congestion control 862 mechanisms such as [I-D.bormann-core-cocoa]. They are required if 863 the main cause for message loss is network or endpoint congestion. 864 Semi-dynamic adjustments could be implemented by disseminating new 865 static transmission parameters to all nodes when the network 866 configuration changes (e.g., new nodes are added or long-lasting 867 interference is detected). 869 4.2. CoAP over IPv4 871 CoAP was designed for the properties of IPv6, which is dominating in 872 constrained environments because of the 6LoWPAN adaption layer 873 [RFC6282]. In particular, the size limitations of CoAP are tailored 874 to the minimal MTU of 1280 bytes. Until the transition towards IPv6 875 converges, CoAP nodes might also communicate over IPv4, though. 876 Sections 4.2 and 4.6 of the base specification [RFC7252] already 877 provide guidance and implementation notes to handle the smaller 878 minimal MTUs of IPv4. 880 5. IANA considerations 882 This document has no actions for IANA. 884 6. Security considerations 886 TBD 888 7. References 890 7.1. Normative References 892 [I-D.bormann-core-cocoa] 893 Bormann, C., Betzler, A., Gomez, C., and I. Demirkol, 894 "CoAP Simple Congestion Control/Advanced", draft-bormann- 895 core-cocoa-02 (work in progress), July 2014. 897 [I-D.ietf-core-block] 898 Bormann, C. and Z. Shelby, "Blockwise transfers in CoAP", 899 draft-ietf-core-block-14 (work in progress), October 2013. 901 [I-D.ietf-core-observe] 902 Hartke, K., "Observing Resources in CoAP", draft-ietf- 903 core-observe-14 (work in progress), June 2014. 905 [RFC6282] Hui, J. and P. Thubert, "Compression Format for IPv6 906 Datagrams over IEEE 802.15.4-Based Networks", RFC 6282, 907 September 2011. 909 [RFC6570] Gregorio, J., Fielding, R., Hadley, M., Nottingham, M., 910 and D. Orchard, "URI Template", RFC 6570, March 2012. 912 [RFC6633] Gont, F., "Deprecation of ICMP Source Quench Messages", 913 RFC 6633, May 2012. 915 [RFC7230] Fielding, R. and J. Reschke, "Hypertext Transfer Protocol 916 (HTTP/1.1): Message Syntax and Routing", RFC 7230, June 917 2014. 919 [RFC7252] Shelby, Z., Hartke, K., and C. Bormann, "The Constrained 920 Application Protocol (CoAP)", RFC 7252, June 2014. 922 7.2. Informative References 924 [Contiki] Dunkels, A., Groenvall, B., and T. Voigt, "Contiki - a 925 Lightweight and Flexible Operating System for Tiny 926 Networked Sensors", Proceedings of the First IEEE Workshop 927 on Embedded Networked Sensors , November 2004. 929 [RFC5927] Gont, F., "ICMP Attacks against TCP", RFC 5927, July 2010. 931 [RFC7228] Bormann, C., Ersue, M., and A. Keranen, "Terminology for 932 Constrained-Node Networks", RFC 7228, May 2014. 934 [TinyOS] Levis, P., Madden, S., Polastre, J., Szewczyk, R., 935 Whitehouse, K., Woo, A., Gay, D., Woo, A., Hill, J., 936 Welsh, M., Brewer, E., and D. Culler, "TinyOS: An 937 Operating System for Sensor Networks", Ambient 938 intelligence, Springer (Berlin Heidelberg), ISBN 939 978-3-540-27139-0 , 2005. 941 Authors' Addresses 942 Matthias Kovatsch 943 ETH Zurich 944 Universitaetstrasse 6 945 CH-8092 Zurich 946 Switzerland 948 Email: kovatsch@inf.ethz.ch 950 Olaf Bergmann 951 Universitaet Bremen TZI 952 Postfach 330440 953 D-28359 Bremen 954 Germany 956 Email: bergmann@tzi.org 958 Esko Dijk 959 Philips Research 961 Email: esko.dijk@philips.com 963 Xuan He 964 Hitachi (China) R&D Corp. 965 301, Tower C North, Raycom, 2 Kexuyuan Nanlu 966 Beijing, 100190 967 P.R.China 969 Email: xhe@hitachi.cn 971 Carsten Bormann (editor) 972 Universitaet Bremen TZI 973 Postfach 330440 974 D-28359 Bremen 975 Germany 977 Phone: +49-421-218-63921 978 Email: cabo@tzi.org