asciidoctor-rfc 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1176 @@
1
+
2
+
3
+
4
+
5
+ CoRE Working Group C. Bormann
6
+ Internet-Draft Universitaet Bremen TZI
7
+ Intended status: Standards Track Z. Shelby, Ed.
8
+ Expires: July 16, 2012 Sensinode
9
+ January 13, 2012
10
+
11
+
12
+ Blockwise transfers in CoAP
13
+ draft-ietf-core-block-05
14
+
15
+ Abstract
16
+
17
+ CoAP is a RESTful transfer protocol for constrained nodes and
18
+ networks. Basic CoAP messages work well for the small payloads we
19
+ expect from temperature sensors, light switches, and similar
20
+ building-automation devices. Occasionally, however, applications
21
+ will need to transfer larger payloads -- for instance, for firmware
22
+ updates. With HTTP, TCP does the grunt work of slicing large
23
+ payloads up into multiple packets and ensuring that they all arrive
24
+ and are handled in the right order.
25
+
26
+ CoAP is based on datagram transports such as UDP or DTLS, which
27
+ limits the maximum size of resource representations that can be
28
+ transferred without too much fragmentation. Although UDP supports
29
+ larger payloads through IP fragmentation, it is limited to 64 KiB
30
+ and, more importantly, doesn't really work well for constrained
31
+ applications and networks.
32
+
33
+ Instead of relying on IP fragmentation, this specification extends
34
+ basic CoAP with a pair of "Block" options, for transferring multiple
35
+ blocks of information from a resource representation in multiple
36
+ request-response pairs. In many important cases, the Block options
37
+ enable a server to be truly stateless: the server can handle each
38
+ block transfer separately, with no need for a connection setup or
39
+ other server-side memory of previous block transfers.
40
+
41
+ In summary, the Block options provide a minimal way to transfer
42
+ larger representations in a block-wise fashion.
43
+
44
+ Status of This Memo
45
+
46
+ This Internet-Draft is submitted in full conformance with the
47
+ provisions of BCP 78 and BCP 79.
48
+
49
+ Internet-Drafts are working documents of the Internet Engineering
50
+ Task Force (IETF). Note that other groups may also distribute
51
+ working documents as Internet-Drafts. The list of current Internet-
52
+ Drafts is at http://datatracker.ietf.org/drafts/current/.
53
+
54
+
55
+
56
+ Bormann & Shelby Expires July 16, 2012 [Page 1]
57
+
58
+ Internet-Draft Blockwise transfers in CoAP January 2012
59
+
60
+
61
+ Internet-Drafts are draft documents valid for a maximum of six months
62
+ and may be updated, replaced, or obsoleted by other documents at any
63
+ time. It is inappropriate to use Internet-Drafts as reference
64
+ material or to cite them other than as "work in progress."
65
+
66
+ This Internet-Draft will expire on July 16, 2012.
67
+
68
+ Copyright Notice
69
+
70
+ Copyright (c) 2012 IETF Trust and the persons identified as the
71
+ document authors. All rights reserved.
72
+
73
+ This document is subject to BCP 78 and the IETF Trust's Legal
74
+ Provisions Relating to IETF Documents
75
+ (http://trustee.ietf.org/license-info) in effect on the date of
76
+ publication of this document. Please review these documents
77
+ carefully, as they describe your rights and restrictions with respect
78
+ to this document. Code Components extracted from this document must
79
+ include Simplified BSD License text as described in Section 4.e of
80
+ the Trust Legal Provisions and are provided without warranty as
81
+ described in the Simplified BSD License.
82
+
83
+ Table of Contents
84
+
85
+ 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2
86
+ 2. Block-wise transfers . . . . . . . . . . . . . . . . . . . . 4
87
+ 2.1. The Block Options . . . . . . . . . . . . . . . . . . . . 5
88
+ 2.2. Using the Block Options . . . . . . . . . . . . . . . . . 9
89
+ 3. Examples . . . . . . . . . . . . . . . . . . . . . . . . . . 11
90
+ 4. HTTP Mapping Considerations . . . . . . . . . . . . . . . . . 16
91
+ 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 17
92
+ 6. Security Considerations . . . . . . . . . . . . . . . . . . . 18
93
+ 6.1. Mitigating Resource Exhaustion Attacks . . . . . . . . . 18
94
+ 6.2. Mitigating Amplification Attacks . . . . . . . . . . . . 19
95
+ 7. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 19
96
+ 8. References . . . . . . . . . . . . . . . . . . . . . . . . . 19
97
+ 8.1. Normative References . . . . . . . . . . . . . . . . . . 19
98
+ 8.2. Informative References . . . . . . . . . . . . . . . . . 20
99
+ Appendix A. Historical Note . . . . . . . . . . . . . . . . . . 20
100
+ Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 20
101
+
102
+ 1. Introduction
103
+
104
+ The CoRE WG is tasked with standardizing an Application Protocol for
105
+ Constrained Networks/Nodes, CoAP. This protocol is intended to
106
+ provide RESTful [REST] services not unlike HTTP [RFC2616], while
107
+ reducing the complexity of implementation as well as the size of
108
+
109
+
110
+
111
+
112
+ Bormann & Shelby Expires July 16, 2012 [Page 2]
113
+
114
+ Internet-Draft Blockwise transfers in CoAP January 2012
115
+
116
+
117
+ packets exchanged in order to make these services useful in a highly
118
+ constrained network of themselves highly constrained nodes.
119
+
120
+ This objective requires restraint in a number of sometimes
121
+ conflicting ways:
122
+
123
+ o reducing implementation complexity in order to minimize code size,
124
+
125
+ o reducing message sizes in order to minimize the number of
126
+ fragments needed for each message (in turn to maximize the
127
+ probability of delivery of the message), the amount of
128
+ transmission power needed and the loading of the limited-bandwidth
129
+ channel,
130
+
131
+ o reducing requirements on the environment such as stable storage,
132
+ good sources of randomness or user interaction capabilities.
133
+
134
+ CoAP is based on datagram transports such as UDP, which limit the
135
+ maximum size of resource representations that can be transferred
136
+ without creating unreasonable levels of IP fragmentation. In
137
+ addition, not all resource representations will fit into a single
138
+ link layer packet of a constrained network, which may cause
139
+ adaptation layer fragmentation even if IP layer fragmentation is not
140
+ required. Using fragmentation (either at the adaptation layer or at
141
+ the IP layer) to enable the transport of larger representations is
142
+ possible up to the maximum size of the underlying datagram protocol
143
+ (such as UDP), but the fragmentation/reassembly process loads the
144
+ lower layers with conversation state that is better managed in the
145
+ application layer.
146
+
147
+ This specification defines a pair of CoAP options to enable _block-
148
+ wise_ access to resource representations. The Block options provide
149
+ a minimal way to transfer larger resource representations in a block-
150
+ wise fashion. The overriding objective is to avoid creating
151
+ conversation state at the server for block-wise GET requests. (It is
152
+ impossible to fully avoid creating conversation state for POST/PUT,
153
+ if the creation/replacement of resources is to be atomic; where that
154
+ property is not needed, there is no need to create server
155
+ conversation state in this case, either.)
156
+
157
+ In summary, this specification adds a pair of Block options to CoAP
158
+ that can be used for block-wise transfers. Benefits of using these
159
+ options include:
160
+
161
+ o Transfers larger than can be accommodated in constrained-network
162
+ link-layer packets can be performed in smaller blocks.
163
+
164
+
165
+
166
+
167
+
168
+ Bormann & Shelby Expires July 16, 2012 [Page 3]
169
+
170
+ Internet-Draft Blockwise transfers in CoAP January 2012
171
+
172
+
173
+ o No hard-to-manage conversation state is created at the adaptation
174
+ layer or IP layer for fragmentation.
175
+
176
+ o The transfer of each block is acknowledged, enabling
177
+ retransmission if required.
178
+
179
+ o Both sides have a say in the block size that actually will be
180
+ used.
181
+
182
+ o The resulting exchanges are easy to understand using packet
183
+ analyzer tools and thus quite accessible to debugging.
184
+
185
+ o If needed, the Block options can also be used as is to provide
186
+ random access to power-of-two sized blocks within a resource
187
+ representation.
188
+
189
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
190
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
191
+ document are to be interpreted as described in RFC 2119, BCP 14
192
+ [RFC2119] and indicate requirement levels for compliant CoAP
193
+ implementations.
194
+
195
+ In this document, the term "byte" is used in its now customary sense
196
+ as a synonym for "octet".
197
+
198
+ Where bit arithmetic is explained, this document uses the notation
199
+ familiar from the programming language C, except that the operator
200
+ "**" stands for exponentiation.
201
+
202
+ 2. Block-wise transfers
203
+
204
+ As discussed in the introduction, there are good reasons to limit the
205
+ size datagrams in constrained networks:
206
+
207
+ o by the maximum datagram size (~ 64 KiB for UDP)
208
+
209
+ o by the desire to avoid IP fragmentation (MTU of 1280 for IPv6)
210
+
211
+ o by the desire to avoid adaptation layer fragmentation (60-80 bytes
212
+ for 6LoWPAN)
213
+
214
+ When a resource representation is larger than can be comfortably
215
+ transferred in the payload of a single CoAP datagram, a Block option
216
+ can be used to indicate a block-wise transfer. As payloads can be
217
+ sent both with requests and with responses, this specification
218
+ provides two separate options for each direction of payload transfer.
219
+
220
+
221
+
222
+
223
+
224
+ Bormann & Shelby Expires July 16, 2012 [Page 4]
225
+
226
+ Internet-Draft Blockwise transfers in CoAP January 2012
227
+
228
+
229
+ In the following, the term "payload" will be used for the actual
230
+ content of a single CoAP message, i.e. a single block being
231
+ transferred, while the term "body" will be used for the entire
232
+ resource representation that is being transferred in a block-wise
233
+ fashion.
234
+
235
+ In most cases, all blocks being transferred for a body will be of the
236
+ same size. The block size is not fixed by the protocol. To keep the
237
+ implementation as simple as possible, the Block options support only
238
+ a small range of power-of-two block sizes, from 2**4 (16) to 2**10
239
+ (1024) bytes. As bodies often will not evenly divide into the power-
240
+ of-two block size chosen, the size need not be reached in the final
241
+ block; still this size will be given as the block size even for the
242
+ final block.
243
+
244
+ 2.1. The Block Options
245
+
246
+ +------+----------+--------+--------+--------+---------------+
247
+ | Type | C/E | Name | Format | Length | Default |
248
+ +------+----------+--------+--------+--------+---------------+
249
+ | 19 | Critical | Block1 | uint | 1-3 B | 0 (see below) |
250
+ | | | | | | |
251
+ | 17 | Critical | Block2 | uint | 1-3 B | 0 (see below) |
252
+ +------+----------+--------+--------+--------+---------------+
253
+
254
+ Table 1: Block Option Numbers
255
+
256
+ Both Block1 and Block2 options can be present both in request and
257
+ response messages. In either case, the Block1 Option pertains to the
258
+ request payload, and the Block2 Option pertains to the response
259
+ payload.
260
+
261
+ Hence, for the methods defined in [I-D.ietf-core-coap], Block1 is
262
+ useful with the payload-bearing POST and PUT requests and their
263
+ responses. Block2 is useful with GET, POST, and PUT requests and
264
+ their payload-bearing responses (2.01, 2.02, 2.04, 2.05 -- see
265
+ section "Payload" of [I-D.ietf-core-coap]).
266
+
267
+ (As a memory aid: Block_1_ pertains to the payload of the _1st_ part
268
+ of the request-response exchange, i.e. the request, and Block_2_
269
+ pertains to the payload of the _2nd_ part of the request-response
270
+ exchange, i.e. the response.)
271
+
272
+ Where Block1 is present in a request or Block2 in a response (i.e.,
273
+ in that message to the payload of which it pertains) it indicates a
274
+ block-wise transfer and describes how this block-wise payload forms
275
+ part of the entire body being transferred ("descriptive usage").
276
+ Where it is present in the opposite direction, it provides additional
277
+
278
+
279
+
280
+ Bormann & Shelby Expires July 16, 2012 [Page 5]
281
+
282
+ Internet-Draft Blockwise transfers in CoAP January 2012
283
+
284
+
285
+ control on how that payload will be formed or was processed ("control
286
+ usage").
287
+
288
+ Implementation of either Block option is intended to be optional.
289
+ However, when it is present in a CoAP message, it MUST be processed
290
+ (or the message rejected); therefore it is identified as a critical
291
+ option.
292
+
293
+ Three items of information may need to be transferred in a Block
294
+ option:
295
+
296
+ o The size of the block (SZX);
297
+
298
+ o whether more blocks are following (M);
299
+
300
+ o the relative number of the block (NUM) within a sequence of blocks
301
+ with the given size.
302
+
303
+ The value of the option is a 1-, 2- or 3-byte integer which encodes
304
+ these three fields, see Figure 1.
305
+
306
+ 0
307
+ 0 1 2 3 4 5 6 7
308
+ +-+-+-+-+-+-+-+-+
309
+ | NUM |M| SZX |
310
+ +-+-+-+-+-+-+-+-+
311
+
312
+ 0 1
313
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
314
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
315
+ | NUM |M| SZX |
316
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
317
+
318
+ 0 1 2
319
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
320
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
321
+ | NUM |M| SZX |
322
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
323
+
324
+ Figure 1: Block option value
325
+
326
+ The block size is encoded as a three-bit unsigned integer (0 for 2**4
327
+ to 6 for 2**10 bytes), which we call the "SZX" (size exponent); the
328
+ actual block size is then "2**(SZX + 4)". SZX is transferred in the
329
+ three least significant bits of the option value (i.e., "val & 7"
330
+ where "val" is the value of the option).
331
+
332
+
333
+
334
+
335
+
336
+ Bormann & Shelby Expires July 16, 2012 [Page 6]
337
+
338
+ Internet-Draft Blockwise transfers in CoAP January 2012
339
+
340
+
341
+ The fourth least significant bit, the M or "more" bit ("val & 8"),
342
+ indicates whether more blocks are following or the current block-wise
343
+ transfer is the last block being transferred.
344
+
345
+ The option value divided by sixteen (the NUM field) is the sequence
346
+ number of the block currently being transferred, starting from zero.
347
+ The current transfer is therefore about the "size" bytes starting at
348
+ byte "NUM << (SZX + 4)". (Note that, as an implementation
349
+ convenience, "(val & ~0xF) << (val & 7)", i.e. the option value with
350
+ the last 4 bits masked out, shifted to the left by the value of SZX,
351
+ gives the byte position of the block.)
352
+
353
+ The default value of both the Block1 and the Block2 Option is zero,
354
+ indicating that the current block is the first and only block of the
355
+ transfer (block number 0, M bit not set); however, there is no
356
+ explicit size implied by this default value.
357
+
358
+ More specifically, within the option value of a Block1 or Block2
359
+ Option, the meaning of the option fields is defined as follows:
360
+
361
+ NUM: Block Number. The block number is a variable-size (4, 12, or
362
+ 20 bit) unsigned integer (uint, see Appendix A of
363
+ [I-D.ietf-core-coap]) indicating the block number being requested
364
+ or provided. Block number 0 indicates the first block of a body.
365
+
366
+ M: More Flag (not last block). For descriptive usage, this flag, if
367
+ unset, indicates that the payload in this message is the last
368
+ block in the body; when set it indicates that there are one or
369
+ more additional blocks available. When a Block2 Option is used in
370
+ a request to retrieve a specific block number ("control usage"),
371
+ the M bit MUST be sent as zero and ignored on reception. (In a
372
+ Block1 Option in a response, the M flag is used to indicate
373
+ atomicity, see below.)
374
+
375
+ SZX: Block Size. The block size is a three-bit unsigned integer
376
+ indicating the size of a block to the power of two. Thus block
377
+ size = 2**(SZX + 4). The allowed values of SZX are 0 to 6, i.e.,
378
+ the minimum block size is 2**(0+4) = 16 and the maximum is
379
+ 2**(6+4) = 1024. The value 7 for SZX (which would indicate a
380
+ block size of 2048) is reserved, i.e. MUST NOT be sent and MUST
381
+ lead to a 4.00 Bad Request response code upon reception in a
382
+ request.
383
+
384
+ The Block options are used in one of three roles:
385
+
386
+ o In descriptive usage, i.e. a Block2 Option in a response (e.g., a
387
+ 2.05 response for GET), or a Block1 Option in a request (e.g., PUT
388
+ or POST):
389
+
390
+
391
+
392
+ Bormann & Shelby Expires July 16, 2012 [Page 7]
393
+
394
+ Internet-Draft Blockwise transfers in CoAP January 2012
395
+
396
+
397
+ * The NUM field in the option value describes what block number
398
+ is contained in the payload of this message.
399
+
400
+ * The M bit indicates whether further blocks are required to
401
+ complete the transfer of that body.
402
+
403
+ * The block size given by SZX MUST match the size of the payload
404
+ in bytes, if the M bit is set. (The block size given is
405
+ irrelevant if M is unset). For Block2, if the request
406
+ suggested a larger value of SZX, the next request MUST move SZX
407
+ down to the size given here. (The effect is that, if the
408
+ server uses the smaller of its preferred block size and the one
409
+ requested, all blocks for a body use the same block size.)
410
+
411
+ o A Block2 Option in control usage in a request (e.g., GET):
412
+
413
+ * The NUM field in the Block2 Option gives the block number of
414
+ the payload that is being requested to be returned in the
415
+ response.
416
+
417
+ * In this case, the M bit has no function and MUST be set to
418
+ zero.
419
+
420
+ * The block size given (SZX) suggests a block size (in the case
421
+ of block number 0) or repeats the block size of previous blocks
422
+ received (in the case of block numbers other than 0).
423
+
424
+ o A Block1 Option in control usage in a response (e.g., a 2.xx
425
+ response for a PUT or POST request):
426
+
427
+ * The NUM field of the Block1 Option indicates what block number
428
+ is being acknowledged.
429
+
430
+ * If the M bit was set in the request, the server can choose
431
+ whether to act on each block separately, with no memory, or
432
+ whether to handle the request for the entire body atomically,
433
+ or any mix of the two. If the M bit is also set in the
434
+ response, it indicates that this response does not carry the
435
+ final response code to the request, i.e. the server collects
436
+ further blocks and plans to implement the request atomically
437
+ (e.g., acts only upon reception of the last block of payload).
438
+ Conversely, if the M bit is unset even though it was set in the
439
+ request, it indicates the block-wise request was enacted now
440
+ specifically for this block, and the response carries the final
441
+ response to this request (and to any previous ones with the M
442
+ bit set in the response's Block1 Option in this sequence of
443
+ block-wise transfers); the client is still expected to continue
444
+
445
+
446
+
447
+
448
+ Bormann & Shelby Expires July 16, 2012 [Page 8]
449
+
450
+ Internet-Draft Blockwise transfers in CoAP January 2012
451
+
452
+
453
+ sending further blocks, the request method for which may or may
454
+ not also be enacted per-block.
455
+
456
+ * Finally, the SZX block size given in a control Block1 Option
457
+ indicates the largest block size preferred by the server for
458
+ transfers toward the resource that is the same or smaller than
459
+ the one used in the initial exchange; the client SHOULD use
460
+ this block size or a smaller one in all further requests in the
461
+ transfer sequence, even if that means changing the block size
462
+ (and possibly scaling the block number accordingly) from now
463
+ on.
464
+
465
+ 2.2. Using the Block Options
466
+
467
+ Using one or both Block options, a single REST operation can be split
468
+ into multiple CoAP message exchanges. As specified in
469
+ [I-D.ietf-core-coap], each of these message exchanges uses their own
470
+ CoAP Message ID.
471
+
472
+ When a request is answered with a response carrying a Block2 Option
473
+ with the M bit set, the requester may retrieve additional blocks of
474
+ the resource representation by sending further requests with the same
475
+ options and a Block2 Option giving the block number and block size
476
+ desired. In a request, the client MUST set the M bit of a Block2
477
+ Option to zero and the server MUST ignore it on reception.
478
+
479
+ To influence the block size used in a response, the requester also
480
+ uses the Block2 Option, giving the desired size, a block number of
481
+ zero and an M bit of zero. A server MUST use the block size
482
+ indicated or a smaller size. Any further block-wise requests for
483
+ blocks beyond the first one MUST indicate the same block size that
484
+ was used by the server in the response for the first request that
485
+ gave a desired size using a Block2 Option.
486
+
487
+ Once the Block2 Option is used by the requester, all requests in a
488
+ single block-wise transfer MUST ultimately use the same size, except
489
+ that there may not be enough content to fill the last block (the one
490
+ returned with the M bit not set). (Note that the client may start
491
+ using the Block2 Option in a second request after a first request
492
+ without a Block2 Option resulted in a Block option in the response.)
493
+ The server SHOULD use the block size indicated in the request option
494
+ or a smaller size, but the requester MUST take note of the actual
495
+ block size used in the response it receives to its initial request
496
+ and proceed to use it in subsequent requests. The server behavior
497
+ MUST ensure that this client behavior results in the same block size
498
+ for all responses in a sequence (except for the last one with the M
499
+ bit not set, and possibly the first one if the initial request did
500
+ not contain a Block2 Option).
501
+
502
+
503
+
504
+ Bormann & Shelby Expires July 16, 2012 [Page 9]
505
+
506
+ Internet-Draft Blockwise transfers in CoAP January 2012
507
+
508
+
509
+ Block-wise transfers can be used to GET resources the representations
510
+ of which are entirely static (not changing over time at all, such as
511
+ in a schema describing a device), or for dynamically changing
512
+ resources. In the latter case, the Block2 Option SHOULD be used in
513
+ conjunction with the ETag Option, to ensure that the blocks being
514
+ reassembled are from the same version of the representation: The
515
+ server SHOULD include an ETag option in each response. If an ETag
516
+ option is available, the client's reassembler, when reassembling the
517
+ representation from the blocks being exchanged, MUST compare ETag
518
+ Options. If the ETag Options do not match in a GET transfer, the
519
+ requester has the option of attempting to retrieve fresh values for
520
+ the blocks it retrieved first. To minimize the resulting
521
+ inefficiency, the server MAY cache the current value of a
522
+ representation for an ongoing sequence of requests. The client MAY
523
+ facilitate identifying the sequence by using the Token Option with a
524
+ non-default value. Note well that this specification makes no
525
+ requirement for the server to establish any state; however, servers
526
+ that offer quickly changing resources may thereby make it impossible
527
+ for a client to ever retrieve a consistent set of blocks.
528
+
529
+ In a request with a request payload (e.g., PUT or POST), the Block1
530
+ Option refers to the payload in the request (descriptive usage).
531
+
532
+ In response to a request with a payload (e.g., a PUT or POST
533
+ transfer), the block size given in the Block1 Option indicates the
534
+ block size preference of the server for this resource (control
535
+ usage). Obviously, at this point the first block has already been
536
+ transferred by the client without benefit of this knowledge. Still,
537
+ the client SHOULD heed the preference and, for all further blocks,
538
+ use the block size preferred by the server or a smaller one. Note
539
+ that any reduction in the block size may mean that the second request
540
+ starts with a block number larger than one, as the first request
541
+ already transferred multiple blocks as counted in the smaller size.
542
+
543
+ To counter the effects of adaptation layer fragmentation on packet
544
+ delivery probability, a client may want to give up retransmitting a
545
+ request with a relatively large payload even before MAX_RETRANSMIT
546
+ has been reached, and try restating the request as a block-wise
547
+ transfer with a smaller payload. Note that this new attempt is then
548
+ a new message-layer transaction and requires a new Message ID.
549
+ (Because of the uncertainty whether the request or the
550
+ acknowledgement was lost, this strategy is useful mostly for
551
+ idempotent requests.)
552
+
553
+ In a blockwise transfer of a request payload (e.g., a PUT or POST)
554
+ that is intended to be implemented in an atomic fashion at the
555
+ server, the actual creation/replacement takes place at the time the
556
+ final block, i.e. a block with the M bit unset in the Block1 Option,
557
+
558
+
559
+
560
+ Bormann & Shelby Expires July 16, 2012 [Page 10]
561
+
562
+ Internet-Draft Blockwise transfers in CoAP January 2012
563
+
564
+
565
+ is received. If not all previous blocks are available at the server
566
+ at this time, the transfer fails and error code 4.08 (Request Entity
567
+ Incomplete) MUST be returned. The error code 4.13 (Request Entity
568
+ Too Large) can be returned at any time by a server that does not
569
+ currently have the resources to store blocks for a block-wise request
570
+ payload transfer that it would intend to implement in an atomic
571
+ fashion.
572
+
573
+ If multiple concurrently proceeding block-wise request payload
574
+ transfer (e.g., PUT or POST) operations are possible, the requester
575
+ SHOULD use the Token Option to clearly separate the different
576
+ sequences. In this case, when reassembling the representation from
577
+ the blocks being exchanged to enable atomic processing, the
578
+ reassembler MUST compare any Token Options present (and, as usual,
579
+ taking an absent Token Option to default to the empty Token). If
580
+ atomic processing is not desired, there is no need to process the
581
+ Token Option (but it is still returned in the response as usual).
582
+
583
+ 3. Examples
584
+
585
+ This section gives a number of short examples with message flows for
586
+ a block-wise GET, and for a PUT or POST. These examples demonstrate
587
+ the basic operation, the operation in the presence of
588
+ retransmissions, and examples for the operation of the block size
589
+ negotiation.
590
+
591
+ In all these examples, a Block option is shown in a decomposed way
592
+ separating the kind of Block option (1 or 2), block number (NUM),
593
+ more bit (M), and block size exponent (2**(SZX+4)) by slashes. E.g.,
594
+ a Block2 Option value of 33 would be shown as 2/2/0/32), or a Block1
595
+ Option value of 59 would be shown as 1/3/1/128.
596
+
597
+ The first example (Figure 2) shows a GET request that is split into
598
+ three blocks. The server proposes a block size of 128, and the
599
+ client agrees. The first two ACKs contain 128 bytes of payload each,
600
+ and third ACK contains between 1 and 128 bytes.
601
+
602
+
603
+
604
+
605
+
606
+
607
+
608
+
609
+
610
+
611
+
612
+
613
+
614
+
615
+
616
+ Bormann & Shelby Expires July 16, 2012 [Page 11]
617
+
618
+ Internet-Draft Blockwise transfers in CoAP January 2012
619
+
620
+
621
+ CLIENT SERVER
622
+ | |
623
+ | CON [MID=1234], GET, /status ------> |
624
+ | |
625
+ | <------ ACK [MID=1234], 2.05 Content, 2/0/1/128 |
626
+ | |
627
+ | CON [MID=1235], GET, /status, 2/1/0/128 ------> |
628
+ | |
629
+ | <------ ACK [MID=1235], 2.05 Content, 2/1/1/128 |
630
+ | |
631
+ | CON [MID=1236], GET, /status, 2/2/0/128 ------> |
632
+ | |
633
+ | <------ ACK [MID=1236], 2.05 Content, 2/2/0/128 |
634
+
635
+ Figure 2: Simple blockwise GET
636
+
637
+ In the second example (Figure 3), the client anticipates the
638
+ blockwise transfer (e.g., because of a size indication in the link-
639
+ format description) and sends a size proposal. All ACK messages
640
+ except for the last carry 64 bytes of payload; the last one carries
641
+ between 1 and 64 bytes.
642
+
643
+ CLIENT SERVER
644
+ | |
645
+ | CON [MID=1234], GET, /status, 2/0/0/64 ------> |
646
+ | |
647
+ | <------ ACK [MID=1234], 2.05 Content, 2/0/1/64 |
648
+ | |
649
+ | CON [MID=1235], GET, /status, 2/1/0/64 ------> |
650
+ | |
651
+ | <------ ACK [MID=1235], 2.05 Content, 2/1/1/64 |
652
+ : :
653
+ : ... :
654
+ : :
655
+ | CON [MID=1238], GET, /status, 2/4/0/64 ------> |
656
+ | |
657
+ | <------ ACK [MID=1238], 2.05 Content, 2/4/1/64 |
658
+ | |
659
+ | CON [MID=1239], GET, /status, 2/5/0/64 ------> |
660
+ | |
661
+ | <------ ACK [MID=1239], 2.05 Content, 2/5/0/64 |
662
+
663
+ Figure 3: Blockwise GET with early negotiation
664
+
665
+ In the third example (Figure 4), the client is surprised by the need
666
+ for a blockwise transfer, and unhappy with the size chosen
667
+ unilaterally by the server. As it did not send a size proposal
668
+ initially, the negotiation only influences the size from the second
669
+
670
+
671
+
672
+ Bormann & Shelby Expires July 16, 2012 [Page 12]
673
+
674
+ Internet-Draft Blockwise transfers in CoAP January 2012
675
+
676
+
677
+ message exchange onward. Since the client already obtained both the
678
+ first and second 64-byte block in the first 128-byte exchange, it
679
+ goes on requesting the third 64-byte block ("2/0/64"). None of this
680
+ is (or needs to be) understood by the server, which simply responds
681
+ to the requests as it best can.
682
+
683
+ CLIENT SERVER
684
+ | |
685
+ | CON [MID=1234], GET, /status ------> |
686
+ | |
687
+ | <------ ACK [MID=1234], 2.05 Content, 2/0/1/128 |
688
+ | |
689
+ | CON [MID=1235], GET, /status, 2/2/0/64 ------> |
690
+ | |
691
+ | <------ ACK [MID=1235], 2.05 Content, 2/2/1/64 |
692
+ | |
693
+ | CON [MID=1236], GET, /status, 2/3/0/64 ------> |
694
+ | |
695
+ | <------ ACK [MID=1236], 2.05 Content, 2/3/1/64 |
696
+ | |
697
+ | CON [MID=1237], GET, /status, 2/4/0/64 ------> |
698
+ | |
699
+ | <------ ACK [MID=1237], 2.05 Content, 2/4/1/64 |
700
+ | |
701
+ | CON [MID=1238], GET, /status, 2/5/0/64 ------> |
702
+ | |
703
+ | <------ ACK [MID=1238], 2.05 Content, 2/5/0/64 |
704
+
705
+ Figure 4: Blockwise GET with late negotiation
706
+
707
+ In all these (and the following) cases, retransmissions are handled
708
+ by the CoAP message exchange layer, so they don't influence the block
709
+ operations (Figure 5, Figure 6).
710
+
711
+
712
+
713
+
714
+
715
+
716
+
717
+
718
+
719
+
720
+
721
+
722
+
723
+
724
+
725
+
726
+
727
+
728
+ Bormann & Shelby Expires July 16, 2012 [Page 13]
729
+
730
+ Internet-Draft Blockwise transfers in CoAP January 2012
731
+
732
+
733
+ CLIENT SERVER
734
+ | |
735
+ | CON [MID=1234], GET, /status ------> |
736
+ | |
737
+ | <------ ACK [MID=1234], 2.05 Content, 2/0/1/128 |
738
+ | |
739
+ | CON [MID=1235], GE///////////////////////// |
740
+ | |
741
+ | (timeout) |
742
+ | |
743
+ | CON [MID=1235], GET, /status, 2/2/0/64 ------> |
744
+ | |
745
+ | <------ ACK [MID=1235], 2.05 Content, 2/2/1/64 |
746
+ : :
747
+ : ... :
748
+ : :
749
+ | CON [MID=1238], GET, /status, 2/5/0/64 ------> |
750
+ | |
751
+ | <------ ACK [MID=1238], 2.05 Content, 2/5/0/64 |
752
+
753
+ Figure 5: Blockwise GET with late negotiation and lost CON
754
+
755
+ CLIENT SERVER
756
+ | |
757
+ | CON [MID=1234], GET, /status ------> |
758
+ | |
759
+ | <------ ACK [MID=1234], 2.05 Content, 2/0/1/128 |
760
+ | |
761
+ | CON [MID=1235], GET, /status, 2/2/0/64 ------> |
762
+ | |
763
+ | //////////////////////////////////tent, 2/2/1/64 |
764
+ | |
765
+ | (timeout) |
766
+ | |
767
+ | CON [MID=1235], GET, /status, 2/2/0/64 ------> |
768
+ | |
769
+ | <------ ACK [MID=1235], 2.05 Content, 2/2/1/64 |
770
+ : :
771
+ : ... :
772
+ : :
773
+ | CON [MID=1238], GET, /status, 2/5/0/64 ------> |
774
+ | |
775
+ | <------ ACK [MID=1238], 2.05 Content, 2/5/0/64 |
776
+
777
+ Figure 6: Blockwise GET with late negotiation and lost ACK
778
+
779
+ The following examples demonstrate a PUT exchange; a POST exchange
780
+ looks the same, with different requirements on atomicity/idempotence.
781
+
782
+
783
+
784
+ Bormann & Shelby Expires July 16, 2012 [Page 14]
785
+
786
+ Internet-Draft Blockwise transfers in CoAP January 2012
787
+
788
+
789
+ To ensure that the blocks relate to the same version of the resource
790
+ representation carried in the request, the client in Figure 7 sets
791
+ the Token to "v17" in all requests. Note that, as with the GET, the
792
+ responses to the requests that have a more bit in the request Block2
793
+ Option are provisional; only the final response tells the client that
794
+ the PUT succeeded.
795
+
796
+ CLIENT SERVER
797
+ | |
798
+ | CON [MID=1234], PUT, /options, v17, 1/0/1/128 ------> |
799
+ | |
800
+ | <------ ACK [MID=1234], 2.04 Changed, 1/0/1/128 |
801
+ | |
802
+ | CON [MID=1235], PUT, /options, v17, 1/1/1/128 ------> |
803
+ | |
804
+ | <------ ACK [MID=1235], 2.04 Changed, 1/1/1/128 |
805
+ | |
806
+ | CON [MID=1236], PUT, /options, v17, 1/2/0/128 ------> |
807
+ | |
808
+ | <------ ACK [MID=1236], 2.04 Changed, 1/2/0/128 |
809
+
810
+ Figure 7: Simple atomic blockwise PUT
811
+
812
+ A stateless server that simply builds/updates the resource in place
813
+ (statelessly) may indicate this by not setting the more bit in the
814
+ response (Figure 8); in this case, the response codes are valid
815
+ separately for each block being updated. This is of course only an
816
+ acceptable behavior of the server if the potential inconsistency
817
+ present during the run of the message exchange sequence does not lead
818
+ to problems, e.g. because the resource being created or changed is
819
+ not yet or not currently in use.
820
+
821
+ CLIENT SERVER
822
+ | |
823
+ | CON [MID=1234], PUT, /options, v17, 1/0/1/128 ------> |
824
+ | |
825
+ | <------ ACK [MID=1234], 2.04 Changed, 1/0/0/128 |
826
+ | |
827
+ | CON [MID=1235], PUT, /options, v17, 1/1/1/128 ------> |
828
+ | |
829
+ | <------ ACK [MID=1235], 2.04 Changed, 1/1/0/128 |
830
+ | |
831
+ | CON [MID=1236], PUT, /options, v17, 1/2/0/128 ------> |
832
+ | |
833
+ | <------ ACK [MID=1236], 2.04 Changed, 1/2/0/128 |
834
+
835
+ Figure 8: Simple stateless blockwise PUT
836
+
837
+
838
+
839
+
840
+ Bormann & Shelby Expires July 16, 2012 [Page 15]
841
+
842
+ Internet-Draft Blockwise transfers in CoAP January 2012
843
+
844
+
845
+ Finally, a server receiving a blockwise PUT or POST may want to
846
+ indicate a smaller block size preference (Figure 9). In this case,
847
+ the client SHOULD continue with a smaller block size; if it does, it
848
+ MUST adjust the block number to properly count in that smaller size.
849
+
850
+ CLIENT SERVER
851
+ | |
852
+ | CON [MID=1234], PUT, /options, v17, 1/0/1/128 ------> |
853
+ | |
854
+ | <------ ACK [MID=1234], 2.04 Changed, 1/0/1/32 |
855
+ | |
856
+ | CON [MID=1235], PUT, /options, v17, 1/4/1/32 ------> |
857
+ | |
858
+ | <------ ACK [MID=1235], 2.04 Changed, 1/4/1/32 |
859
+ | |
860
+ | CON [MID=1236], PUT, /options, v17, 1/5/1/32 ------> |
861
+ | |
862
+ | <------ ACK [MID=1235], 2.04 Changed, 1/5/1/32 |
863
+ | |
864
+ | CON [MID=1237], PUT, /options, v17, 1/6/0/32 ------> |
865
+ | |
866
+ | <------ ACK [MID=1236], 2.04 Changed, 1/6/0/32 |
867
+
868
+ Figure 9: Simple atomic blockwise PUT with negotiation
869
+
870
+ 4. HTTP Mapping Considerations
871
+
872
+ In this subsection, we give some brief examples for the influence the
873
+ Block options might have on intermediaries that map between CoAP and
874
+ HTTP.
875
+
876
+ For mapping CoAP requests to HTTP, the intermediary may want to map
877
+ the sequence of block-wise transfers into a single HTTP transfer.
878
+ E.g., for a GET request, the intermediary could perform the HTTP
879
+ request once the first block has been requested and could then
880
+ fulfill all further block requests out of its cache. A constrained
881
+ implementation may not be able to cache the entire object and may use
882
+ a combination of TCP flow control and (in particular if timeouts
883
+ occur) HTTP range requests to obtain the information necessary for
884
+ the next block transfer at the right time.
885
+
886
+ For PUT or POST requests, there is more variation in how HTTP servers
887
+ might implement ranges. Some WebDAV servers do, but in general the
888
+ CoAP-to-HTTP intermediary will have to try sending the payload of all
889
+ the blocks of a block-wise transfer within one HTTP request. If
890
+ enough buffering is available, this request can be started when the
891
+ last CoAP block is received. A constrained implementation may want
892
+ to relieve its buffering by already starting to send the HTTP request
893
+
894
+
895
+
896
+ Bormann & Shelby Expires July 16, 2012 [Page 16]
897
+
898
+ Internet-Draft Blockwise transfers in CoAP January 2012
899
+
900
+
901
+ at the time the first CoAP block is received; any HTTP 408 status
902
+ code that indicates that the HTTP server became impatient with the
903
+ resulting transfer can then be mapped into a CoAP 4.08 response code
904
+ (similarly, 413 maps to 4.13).
905
+
906
+ For mapping HTTP to CoAP, the intermediary may want to map a single
907
+ HTTP transfer into a sequence of block-wise transfers. If the HTTP
908
+ client is too slow delivering a request body on a PUT or POST, the
909
+ CoAP server might time out and return a 4.08 response code, which in
910
+ turn maps well to an HTTP 408 status code (again, 4.13 maps to 413).
911
+ HTTP range requests received on the HTTP side may be served out of a
912
+ cache and/or mapped to GET requests that request a sequence of blocks
913
+ overlapping the range.
914
+
915
+ (Note that, while the semantics of CoAP 4.08 and HTTP 408 differ,
916
+ this difference is largely due to the different way the two protocols
917
+ are mapped to transport. HTTP has an underlying TCP connection,
918
+ which supplies connection state, so a HTTP 408 status code can
919
+ immediately be used to indicate that a timeout occurred during
920
+ transmitting a request through that active TCP connection. The CoAP
921
+ 4.08 response code indicates one or more missing blocks, which may be
922
+ due to timeouts or resource constraints; as there is no connection
923
+ state, there is no way to deliver such a response immediately;
924
+ instead, it is delivered on the next block transfer. Still, HTTP 408
925
+ is probably the best mapping back to HTTP, as the timeout is the most
926
+ likely cause for a CoAP 4.08. Note that there is no way to
927
+ distinguish a timeout from a missing block for a server without
928
+ creating additional state, the need for which we want to avoid.)
929
+
930
+ 5. IANA Considerations
931
+
932
+ This draft adds the following option numbers to the CoAP Option
933
+ Numbers registry of [I-D.ietf-core-coap]:
934
+
935
+ +--------+--------+-----------+
936
+ | Number | Name | Reference |
937
+ +--------+--------+-----------+
938
+ | 17 | Block2 | [RFCXXXX] |
939
+ | | | |
940
+ | 19 | Block1 | [RFCXXXX] |
941
+ +--------+--------+-----------+
942
+
943
+ Table 2: CoAP Option Numbers
944
+
945
+ This draft adds the following response code to the CoAP Response
946
+ Codes registry of [I-D.ietf-core-coap]:
947
+
948
+
949
+
950
+
951
+
952
+ Bormann & Shelby Expires July 16, 2012 [Page 17]
953
+
954
+ Internet-Draft Blockwise transfers in CoAP January 2012
955
+
956
+
957
+ +------+--------------------------------+-----------+
958
+ | Code | Description | Reference |
959
+ +------+--------------------------------+-----------+
960
+ | 136 | 4.08 Request Entity Incomplete | [RFCXXXX] |
961
+ +------+--------------------------------+-----------+
962
+
963
+ Table 3: CoAP Response Codes
964
+
965
+ 6. Security Considerations
966
+
967
+ Providing access to blocks within a resource may lead to surprising
968
+ vulnerabilities. Where requests are not implemented atomically, an
969
+ attacker may be able to exploit a race condition or confuse a server
970
+ by inducing it to use a partially updated resource representation.
971
+ Partial transfers may also make certain problematic data invisible to
972
+ intrusion detection systems; it is RECOMMENDED that an intrusion
973
+ detection system (IDS) that analyzes resource representations
974
+ transferred by CoAP implement the Block options to gain access to
975
+ entire resource representations. Still, approaches such as
976
+ transferring even-numbered blocks on one path and odd-numbered blocks
977
+ on another path, or even transferring blocks multiple times with
978
+ different content and obtaining a different interpretation of
979
+ temporal order at the IDS than at the server, may prevent an IDS from
980
+ seeing the whole picture. These kinds of attacks are well understood
981
+ from IP fragmentation and TCP segmentation; CoAP does not add
982
+ fundamentally new considerations.
983
+
984
+ Where access to a resource is only granted to clients making use of a
985
+ specific security association, all blocks of that resource MUST be
986
+ subject to the same security checks; it MUST NOT be possible for
987
+ unprotected exchanges to influence blocks of an otherwise protected
988
+ resource. As a related consideration, where object security is
989
+ employed, PUT/POST should be implemented in the atomic fashion,
990
+ unless the object security operation is performed on each access and
991
+ the creation of unusable resources can be tolerated.
992
+
993
+ 6.1. Mitigating Resource Exhaustion Attacks
994
+
995
+ Certain blockwise requests may induce the server to create state,
996
+ e.g. to create a snapshot for the blockwise GET of a fast-changing
997
+ resource to enable consistent access to the same version of a
998
+ resource for all blocks, or to create temporary resource
999
+ representations that are collected until pressed into service by a
1000
+ final PUT or POST with the more bit unset. All mechanisms that
1001
+ induce a server to create state that cannot simply be cleaned up
1002
+ create opportunities for denial-of-service attacks. Servers SHOULD
1003
+ avoid being subject to resource exhaustion based on state created by
1004
+ untrusted sources. But even if this is done, the mitigation may
1005
+
1006
+
1007
+
1008
+ Bormann & Shelby Expires July 16, 2012 [Page 18]
1009
+
1010
+ Internet-Draft Blockwise transfers in CoAP January 2012
1011
+
1012
+
1013
+ cause a denial-of-service to a legitimate request when it is drowned
1014
+ out by other state-creating requests. Wherever possible, servers
1015
+ should therefore minimize the opportunities to create state for
1016
+ untrusted sources, e.g. by using stateless approaches.
1017
+
1018
+ Performing segmentation at the application layer is almost always
1019
+ better in this respect than at the transport layer or lower (IP
1020
+ fragmentation, adaptation layer fragmentation), e.g. because there is
1021
+ application layer semantics that can be used for mitigation or
1022
+ because lower layers provide security associations that can prevent
1023
+ attacks. However, it is less common to apply timeouts and keepalive
1024
+ mechanisms at the application layer than at lower layers. Servers
1025
+ MAY want to clean up accumulated state by timing it out (cf. response
1026
+ code 4.08), and clients SHOULD be prepared to run blockwise transfers
1027
+ in an expedient way to minimize the likelihood of running into such a
1028
+ timeout.
1029
+
1030
+ 6.2. Mitigating Amplification Attacks
1031
+
1032
+ [I-D.ietf-core-coap] discusses the susceptibility of CoAP end-points
1033
+ for use in amplification attacks.
1034
+
1035
+ A CoAP server can reduce the amount of amplification it provides to
1036
+ an attacker by offering large resource representations only in
1037
+ relatively small blocks. With this, e.g., for a 1000 byte resource,
1038
+ a 10-byte request might result in an 80-byte response (with a 64-byte
1039
+ block) instead of a 1016-byte response, considerably reducing the
1040
+ amplification provided.
1041
+
1042
+ 7. Acknowledgements
1043
+
1044
+ Much of the content of this draft is the result of discussions with
1045
+ the [I-D.ietf-core-coap] authors, and via many CoRE WG discussions.
1046
+ Tokens were suggested by Gilman Tolle and refined by Klaus Hartke.
1047
+
1048
+ Charles Palmer provided extensive editorial comments to a previous
1049
+ version of this draft, some of which the authors hope to have covered
1050
+ in this version.
1051
+
1052
+ 8. References
1053
+
1054
+ 8.1. Normative References
1055
+
1056
+ [I-D.ietf-core-coap]
1057
+ Shelby, Z., Hartke, K., and C. Bormann, "Constrained
1058
+ Application Protocol (CoAP)", draft-ietf-core-coap-18
1059
+ (work in progress), June 2013.
1060
+
1061
+
1062
+
1063
+
1064
+ Bormann & Shelby Expires July 16, 2012 [Page 19]
1065
+
1066
+ Internet-Draft Blockwise transfers in CoAP January 2012
1067
+
1068
+
1069
+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
1070
+ Requirement Levels", BCP 14, RFC 2119,
1071
+ DOI 10.17487/RFC2119, March 1997,
1072
+ <https://www.rfc-editor.org/info/rfc2119>.
1073
+
1074
+ [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
1075
+ Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext
1076
+ Transfer Protocol -- HTTP/1.1", RFC 2616,
1077
+ DOI 10.17487/RFC2616, June 1999,
1078
+ <https://www.rfc-editor.org/info/rfc2616>.
1079
+
1080
+ 8.2. Informative References
1081
+
1082
+ [REST] Fielding, R., "Architectural Styles and the Design of
1083
+ Network-based Software Architectures", 2000.
1084
+
1085
+ Appendix A. Historical Note
1086
+
1087
+ (This appendix to be deleted by the RFC editor.)
1088
+
1089
+ An earlier version of this draft used a single option:
1090
+
1091
+ +------+----------+-------+--------+--------+---------------+
1092
+ | Type | C/E | Name | Format | Length | Default |
1093
+ +------+----------+-------+--------+--------+---------------+
1094
+ | 13 | Critical | Block | uint | 1-3 B | 0 (see below) |
1095
+ +------+----------+-------+--------+--------+---------------+
1096
+
1097
+ Note that this option number has since been reallocated in
1098
+ [I-D.ietf-core-coap]; no backwards compatibility is provided after
1099
+ July 1st, 2011.
1100
+
1101
+ Authors' Addresses
1102
+
1103
+ Carsten Bormann
1104
+ Universitaet Bremen TZI
1105
+ Postfach 330440
1106
+ Bremen D-28359
1107
+ Germany
1108
+
1109
+ Phone: +49-421-218-63921
1110
+ Fax: +49-421-218-7000
1111
+ Email: cabo@tzi.org
1112
+
1113
+
1114
+
1115
+
1116
+
1117
+
1118
+
1119
+
1120
+ Bormann & Shelby Expires July 16, 2012 [Page 20]
1121
+
1122
+ Internet-Draft Blockwise transfers in CoAP January 2012
1123
+
1124
+
1125
+ Zach Shelby (editor)
1126
+ Sensinode
1127
+ Kidekuja 2
1128
+ Vuokatti 88600
1129
+ Finland
1130
+
1131
+ Phone: +358407796297
1132
+ Email: zach@sensinode.com
1133
+
1134
+
1135
+
1136
+
1137
+
1138
+
1139
+
1140
+
1141
+
1142
+
1143
+
1144
+
1145
+
1146
+
1147
+
1148
+
1149
+
1150
+
1151
+
1152
+
1153
+
1154
+
1155
+
1156
+
1157
+
1158
+
1159
+
1160
+
1161
+
1162
+
1163
+
1164
+
1165
+
1166
+
1167
+
1168
+
1169
+
1170
+
1171
+
1172
+
1173
+
1174
+
1175
+
1176
+ Bormann & Shelby Expires July 16, 2012 [Page 21]