idnits 2.17.1 draft-iyengar-minion-protocol-00.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 (June 30, 2013) is 3950 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Possible downref: Non-RFC (?) normative reference: ref. 'COBS' ** Obsolete normative reference: RFC 793 (Obsoleted by RFC 9293) ** Obsolete normative reference: RFC 6347 (Obsoleted by RFC 9147) Summary: 2 errors (**), 0 flaws (~~), 1 warning (==), 2 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group J. Iyengar 3 Internet-Draft Franklin and Marshall College 4 Intended status: Standards Track S. Cheshire 5 Expires: January 01, 2014 J. Graessley 6 Apple 7 June 30, 2013 9 Minion - Wire Protocol 10 draft-iyengar-minion-protocol-00 12 Abstract 14 Minion uses TCP-format packets on-the-wire, for compatibility with 15 existing NATs, Firewalls, and similar middleboxes, but provides a 16 richer set of facilities to the application, as described in the 17 Minion Service Model document. This document specifies the details 18 of the on-the-wire protocol used to provide those services. 20 Status of This Memo 22 This Internet-Draft is submitted in full conformance with the 23 provisions of BCP 78 and BCP 79. 25 Internet-Drafts are working documents of the Internet Engineering 26 Task Force (IETF). Note that other groups may also distribute 27 working documents as Internet-Drafts. The list of current Internet- 28 Drafts is at http://datatracker.ietf.org/drafts/current/. 30 Internet-Drafts are draft documents valid for a maximum of six months 31 and may be updated, replaced, or obsoleted by other documents at any 32 time. It is inappropriate to use Internet-Drafts as reference 33 material or to cite them other than as "work in progress." 35 This Internet-Draft will expire on January 01, 2014. 37 Copyright Notice 39 Copyright (c) 2013 IETF Trust and the persons identified as the 40 document authors. All rights reserved. 42 This document is subject to BCP 78 and the IETF Trust's Legal 43 Provisions Relating to IETF Documents 44 (http://trustee.ietf.org/license-info) in effect on the date of 45 publication of this document. Please review these documents 46 carefully, as they describe your rights and restrictions with respect 47 to this document. Code Components extracted from this document must 48 include Simplified BSD License text as described in Section 4.e of 49 the Trust Legal Provisions and are provided without warranty as 50 described in the Simplified BSD License. 52 1. Conventions and Terminology Used in this Document 54 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 55 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 56 "OPTIONAL" in this document are to be interpreted as described in 57 "Key words for use in RFCs to Indicate Requirement Levels" [RFC2119]. 59 This document uses terminology like "kernel" and "user-level", as 60 those terms pertain to many of today's Unix-like operating systems. 61 Equivalent concepts apply to software that is built using a different 62 architectural model than may not include such an obvious kernel/user 63 split. 65 2. Introduction 67 Minion uses TCP-format packets on-the-wire, to provide full 68 compatibility with existing NATs, Firewalls, and similar middleboxes, 69 but provides a richer set of facilities to the application, described 70 in the Minion Service Model and Conceptual API document [minserv]. 71 This document specifies the details of the on-the-wire protocol used 72 to provide those services. Before reading this protocol 73 specification document, familiarity with the Minion Service Model 74 [minserv] is strongly recommended. That information is not repeated 75 here. 77 Minion runs over a standard TCP connection. Therefore, IP addresses 78 and TCP ports are used just as they are with TCP [RFC0793]. 80 Minion is also designed to be able to use a modified TCP connection 81 which supports out-of-order delivery, giving better low-latency 82 performance on lossy networks, for use by the kinds of application 83 that today would use UDP [RFC0768] to achieve low-latency delivery. 84 The goal of providing low-latency delivery -- and consequently the 85 need to be able to handle a data stream that may have gaps -- is 86 reflected in various aspects of the Minion protocol design, such as 87 the use of DTLS instead of TLS, and the use of Consistent Overhead 88 Byte Stuffing [COBS] for reliably extracting messages from an 89 incomplete data stream. Minion is able to take advantage of out-of- 90 order delivery where the network stack offers that, but Minion does 91 not require it. Minion still works correctly when the performance 92 benefits of out-of-order delivery are not available. 94 Minion supports messages of arbitrary size. Large messages are 95 broken into chunks a little under 16 kilobytes each (the DTLS maximum 96 record size, minus a few bytes for Minion header). At the receiving 97 end the Minion chunks are reassembled into Minion messages and 98 delivered to the client application. Small messages are sent in a 99 single Minion chunk. 101 Normally messages are sent by the client as a single atomic unit, and 102 delivered to the receiving client as a single atomic unit. For 103 messages too large to fit conveniently in memory, the message may be 104 built incrementally by the sender, and delivered to the receiving 105 client incrementally, a chunk at a time. 107 When a Minion message is complete, or has at least one maximum Minion 108 chunk size of data accumulated, then if it is eligible to be sent 109 according to the message ordering facilities offered by the Minion 110 Service Model [minserv] (Sender Ordering, Receiver Ordering, and 111 Chaining) a Minion chunk is generated. 113 Each Minion chunk contains a Minion chunk header followed by the 114 client's message data, as described in Section 3 "Minion Chunk 115 Format". 117 Each Minion chunk is encrypted using DTLS [RFC6347]. 119 Each encrypted DTLS payload is then framed using RECOBS, as described 120 in Section 4 "Recursively Embeddable COBS", so that it begins with a 121 00 byte and ends with an FF byte. 123 The framed, encrypted chunk is then enqueued for transmission. 125 If the kernel networking code supports multiple priorities, then the 126 framed, encrypted chunk is placed in the transmission queue for the 127 stated priority level. Any time the TCP congestion window and/or 128 receive window rules allow more data to be sent, data is drawn from 129 the highest-priority non-empty transmit buffer, assigned the next 130 block of unused TCP sequence numbers, formed into a TCP segment, and 131 transmitted on the wire. This just-in-time TCP sequencing mechanism 132 has the effect of causing higher-priority data to be inserted right 133 at the front of the conceptual combined transmit buffer, at the 134 earliest possible byte boundary, unconstrained by message or chunk 135 boundaries in the lower-priority messages. This is possible because 136 the RECOBS framing is robust to pre-emption at any arbitrary byte 137 boundary. 139 Note that, when priorities are supported, chunks above the lowest 140 priority MUST be delivered to the kernel in such a way that they are 141 sent completely before the kernel resumes sending the lower-priority 142 traffic. The RECOBS framing supports interrupting a lower priority 143 stream with a higher-priority chunk, but not alternating back and 144 forth between two priority levels. Once a higher-priority chunk 145 interrupts lower-priority traffic, the higher-priority chunk must be 146 completed before the lower-priority traffic resumes. Typically this 147 is easily achieved by delivering the chunk to the kernel atomically 148 in a single write call. 150 3. Minion Chunk Format 152 A Minion Chunk begins with an eight-byte header, followed by the 153 client's message data: 155 0 1 2 3 156 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 157 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 158 |C| Code |Pri| This Minion Chunk ID | 159 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 160 | Reserved |RCP| Referenced Minion Chunk ID | 161 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 162 : : 163 : Minion Chunk Data : 164 : : 165 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 167 Figure 1: Minion Chunk Format 169 If the Complete ('C') bit is zero, this message is incomplete; the 170 receiver should expect to receive additional continuation chunks for 171 this message. If the Complete bit is one, this message is complete; 172 there will be no subsequent continuation chunks for this message. 174 The seven-bit chunk code identifies what type of chunk this is, as 175 described below. 177 The two-bit priority field indicates the priority level for this 178 message, with 0 being the highest priority and 3 being the default 179 (lowest-level) priority. 181 Every Minion chunk has a Chunk ID. This is a 22-bit value assigned 182 from a monotonically increasing 22-bit cyclic counter. This means 183 that Chunk IDs are reused every 2^22 chunks. At any given moment in 184 time though, only a small portion of the 22-bit ID space is actively 185 in use, so Chunk IDs are not ambiguous. Each of the four priority 186 levels has its own 22-bit Chunk ID space, i.e., Priority 1 Chunk 7 187 and Priority 2 Chunk 7 are different chunks. Also, the Chunk ID 188 spaces in opposite directions on a connection are separate. Each 189 sender is responsible for selecting the Chunk IDs for the chunks it 190 sends. 192 In some cases it is useful to refer to messages by ID, and the terms 193 "Message ID" and "Chunk ID" are sometimes used interchangeably. For 194 a message that is sent using a single chunk, the Message ID is the 195 same as the Chunk ID. For a message that is sent using multiple 196 chunks, the Message ID is the Chunk ID of the *final* chunk of the 197 message. One implication of this is that a message's ID is undefined 198 until the message is complete. 200 Because Chunk IDs are eventually reused, issues of ID lifetime must 201 be carefully considered in the Minion protocol design. For example, 202 since a remote peer could, in principle, wait an arbitrary long 203 length of time before replying to a message, the Message ID of a 204 request that is awaiting a response MUST NOT be reused until the 205 response has been received, and the client has disposed of the 206 request message. Otherwise, a reply could be ambiguous, if there 207 were two outstanding request messages both using the same Message ID 208 at the same time. Likewise, the last Chunk ID of an incomplete 209 message MUST NOT be reused until some subsequent chunk has been added 210 to that message, referencing the previous Chunk ID. 212 The Reserved field MUST be set to zero on transmission, and MUST be 213 ignored on reception. 215 For chunk types that need to refer to some other chunk, the 216 Referenced Minion Chunk Priority (RCP) and Referenced Minion Chunk ID 217 fields identify the referenced chunk. Note that some chunk types 218 refer to chunks going in the same direction (e.g. a continuation 219 chunk) and some chunk types refer to chunks going in the reverse 220 direction (e.g. a reply chunk). For chunk types that do not to refer 221 to any other chunk, these two fields MUST be set to zero on 222 transmission, and MUST be ignored on reception. 224 The Minion Chunk payload data follows the Minion Chunk Header. 226 There is no explicit length field in the Minion Chunk Header, because 227 the chunk length is determined implicitly in the RECOBS decoding 228 step. 230 3.1. Minion Chunk Codes 232 The seven-bit chunk code identifies what kind of chunk this is. 128 233 chunk codes are available. The following eight chunk codes are 234 currently defined: 236 00 Continuation. This is a continuation of a previously incomplete 237 message. The Referenced Minion Chunk ID identifies what 238 previous chunk this is adding to. (If the Complete bit is one 239 then this chunk is the final chunk and completes the message; no 240 further chunks for this message will be arriving.) 242 01 Cancellation. This is a cancellation of a previously incomplete 243 message. The Referenced Minion Chunk ID identifies what 244 previous chunk this is cancelling. In this case Complete bit is 245 unused; the Complete bit MUST be set to zero on transmission, 246 and MUST be ignored on reception. 248 02 Unordered Message. This chunk begins a new unordered message. 249 The Referenced Minion Chunk ID is unused, and MUST be set to 250 zero on transmission, and MUST be ignored on reception. 252 03 Ordered Message. This chunk begins a new ordered message. This 253 message is subject to Receiver Ordering; it MUST NOT be 254 delivered to the receiving client until the message indicated by 255 the Referenced Minion Chunk ID field has been delivered. 257 04 Chained Message. This chunk begins a new message that chains on 258 after a preceding message. The Referenced Minion Chunk ID 259 identifies the preceding message. This message MUST NOT be 260 delivered to the receiving client until the previous message of 261 the chain as been delivered to the receiving client, and this 262 message MUST be delivered to the receiving client in a manner 263 that indicates to the client that it is related to the previous 264 message. 266 05 Reply/Acknowledge. This chunk begins a new message which is an 267 explicit reply to a previously received message. The Referenced 268 Minion Chunk ID identifies the received message to which this is 269 a reply. A reply may be empty, in which case it serves as a 270 simple acknowledgement that the request was received and 271 accepted, or it may contain data. It is anticipated that future 272 Minion protocol development will create additional Minion chunk 273 codes to negotiate future protocol features. For these 274 capability negotiation messages, an empty reply referencing the 275 request serves as an acknowledgement that the requested protocol 276 feature is supported. 278 06 Reject. A Minion Reject code indicates that the referenced 279 received message had an error or was not accepted for some other 280 reason. A Reject Message may be empty, or may contain data 281 giving information concerning the reason for the rejection. It 282 is possible to reject an incomplete message that is still 283 arriving, by sending a Reject referencing the most recent Chunk 284 ID for that partial message. The sender will respond by sending 285 a Cancellation for that message, confirming that no further 286 chunks will be sent. When used for Minion protocol capability 287 negotiation, a Reject message referencing the request indicates 288 that the requested protocol feature is not supported. 290 07 End Minion. It is anticipated that there will be existing 291 application protocols that initially add Minion as an optional 292 feature, which they use only when the remote peer indicates it 293 also has Minion support, and otherwise they will communicate 294 using the existing protocol without the Minion features. Such 295 application protocols typically will first connect using their 296 existing protocol, and then negotiate an "upgrade" to Minion 297 framing. For symmetry, it would be good if such an "upgrade" 298 were not an irreversible one-way path. We would like to offer 299 the ability for applications to connect over raw TCP, switch to 300 Minion for some message exchanges, and then drop back to raw TCP 301 for some subsequent communication. For this reason the Minion 302 chunk code 8 exists, which signals, "This is the final Minion- 303 format message you will receive in this particular Minion 304 session; after this you're on your own." 306 4. Recursively Embeddable COBS 308 Consistent Overhead Byte Stuffing [COBS] allows complete messages to 309 be reliably located within an incomplete data stream that may contain 310 gaps. 312 COBS works by transforming the payload data to eliminate all 313 occurrences of zero bytes. This is like PPP byte stuffing, but more 314 efficient; COBS has a worst-case data size overhead below 0.5%. 315 Having created a zero-free payload, the payloads can then be 316 concatenated into a single byte stream, separated by single zero 317 bytes, and the zero bytes unambiguously mark the boundaries between 318 payloads, because we know the payloads themselves no longer contain 319 any zero bytes. At the receiving end the transformation is reversed 320 to recreate the original payload data. 322 The transformation process [COBS] is, in effect, a simple run length 323 encoding. An extremely simplified summary of the original 1997 COBS 324 encoding is as follows: 326 o If the payload begins with three nonzero bytes followed by a zero, 327 then the output is the byte value 4 (the run length) followed by 328 the three nonzero bytes, and the subsequent zero is skipped. 330 o If that is followed by fifty nonzero bytes followed by a zero, 331 then the output is the byte value 51 (the run length) followed by 332 the fifty nonzero bytes, and the subsequent zero is skipped. 334 o This process is repeated until the entire payload has been 335 replaced by its zero-free equivalent. 337 Recursively Embeddable COBS (RECOBS) is a derivative of the original 338 1997 COBS encoding. RECOBS code bytes have the following meanings: 340 00 New payload begins 341 01 Represents a single zero byte 342 02 Two bytes: a single nonzero byte, followed by a single zero byte 343 03 Three bytes: two nonzero bytes, followed by a single zero byte 344 n Represents n bytes: n-1 nonzero bytes, followed by a zero byte 345 FD 253 bytes: 252 nonzero bytes, followed by a single zero byte 346 FE 253 bytes: 253 nonzero bytes, with *no* following zero byte 347 FF Payload ends 349 This has the effect that, after encoding, every payload has 350 unambiguous bookends; every payload begins with a single 00, and ends 351 with a single FF. Using this encoding, recursive embedding becomes 352 possible. At *any* point in the encoded byte stream it is now 353 possible to interrupt the byte stream, insert a new RECOBS-encoded 354 payload, and then resume the previous byte stream. 356 At the receiving end, the decoder is part-way through decoding a 357 payload when the interruption occurs. The decoder sees a 00, which 358 is not legal in RECOBS-encoded data, so the decoder knows a new 359 payload is beginning. Because the decoder has not yet seen the FF 360 end-marker for the previous payload, it knows that payload is 361 incomplete, so it saves its decoding state for later resumption. The 362 decoder then proceeds to decode the embedded payload. When the 363 decoder sees the FF end-marker for the embedded payload, it delivers 364 that fully decoded payload to the waiting client, and then resumes 365 its decoding of the previously interrupted payload. 367 In principle this recursive embedding could be nested arbitrarily 368 deeply, limited only by the amount of storage the decoder has 369 available for partially-received payloads and their associated 370 decoding state. 372 In practice, Minion limits RECOBS embedding to four levels (the base 373 level plus three levels of nested interruption) to establish a 374 defined upper bound on the amount of storage required by a decoder. 376 5. Flow Control 377 TCP [RFC0793] implements flow control in the form of the advertised 378 receive window. This is to prevent a faster sender from overwhelming 379 a slower receiver. Minion requires similar protection to prevent a 380 slower receiver running out of memory trying to buffer messages 381 arriving faster than it can handle them. 383 For a pure user-level library implementation of Minion, this is 384 achieved by having the library set an upper bound on the amount of 385 memory it will use for storing received messages that have not yet 386 been handled by the client. Once this limit is met, the library 387 ceases reading TCP data from the kernel, which causes the TCP receive 388 window to fill up, which causes the sender to stop sending. Once the 389 client consumes some messages, the library then reads more data from 390 the kernel, the TCP receive window opens up, and the sender is 391 permitted to send more data. 393 However, this means that there is some duplication of buffering -- 394 the TCP receive window in the kernel and additional buffering in the 395 user-level library. For this reason a kernel extension is proposed 396 where a client (the Minion library in this case) can read data from 397 the connection *without* raising the TCP receive window. In a sense 398 it is reading the data "secretly", without admitting to the sender at 399 the other end that it has been read. Those bytes, even though read 400 into user space, are still counted against the TCP receive window. 401 Later, after the client application has actually consumed the 402 message, another kernel call is made to acknowledge consumption of 403 those bytes, and the TCP receive window is raised. 405 This mechanism integrates message-level flow control with TCP's byte- 406 level flow control, rather than having two independent flow control 407 mechanisms happening concurrently at different levels, in ways that 408 might interact badly with each other. 410 Note that the Minion protocol design will have to consider possible 411 deadlock situations. For example, suppose one Minion host is 412 refusing to consume any more Minion Chunks because it wishes to send 413 a Reject message for them, but it cannot, because the peer's receive 414 window is closed. Suppose also that the reason the peer's receive 415 window is closed is because the peer also is sitting on a pile of 416 unwanted Minion Chunks that it refuses to consume until it can send a 417 Reject message for them. Possible deadlocks such as these need to be 418 considered, and mechanisms to avoid them created. 420 6. Retransmission Policy 422 One of the main arguments that is often presented to justify why a 423 particular application protocol is built on UDP instead of TCP is 424 that, "UDP is better for 'real time' applications." The supporting 425 reasoning for this is often that, "TCP insists on continuing to 426 retransmit data long after the client doesn't need any more." In 427 truth the real problem is not retransmission; it is that the 428 conventional TCP APIs don't allow received data to be delivered out 429 of order. Suppose a TCP sender has 50 packets in flight at any given 430 time (e.g. the bandwidth x delay product is 75 kB) then the loss of a 431 single packet causes all 49 following packets to stall at the 432 receiver because the API doesn't allow for them to be delivered to 433 the client until the missing packet has been received. 435 Minion solves this problem by allowing data to be delivered as it 436 arrives, even if there are gaps. But the argument still remains that 437 even after removing the ordering requirement at the receiver, it may 438 still be a waste of bandwidth to retransmit data that will arrive too 439 late to be useful. And indeed, it is possible with TCP to 440 fraudulently acknowledge segments that were in fact not received, and 441 this will cause the sender to not retransmit those segments. 443 However, we chose not to use fraudulent acknowledgements to suppress 444 retransmissions, because certain NATs, Firewalls and other 445 middleboxes may block traffic if they observe implausible protocol 446 actions which they find suspicious. One of the important goals of 447 Minion is 100% compatibility with today's existing Internet devices, 448 not 99% compatibility. 450 We expect packet loss to be about 1% (at most a few percent) in a 451 functioning network, and the cost of retransmitting those lost 452 packets, even in the extreme case where *all* the retransmissions 453 turn out to be unnecessary, is an overhead of about 1%. We argue that 454 an overhead of about 1% is an acceptable price to pay in exchange for 455 100% compatibility with existing NATs, Firewalls and other 456 middleboxes. 458 7. Optional Kernel Extensions 460 While Minion can be implemented entirely as a user-level library 461 built on top of existing standard networking APIs like BSD sockets, 462 it can also benefit from some optional kernel extensions: 464 Send Priorities 465 Normal TCP APIs transmit data strictly in the order is is given to 466 the kernel. The addition of priority support allows a sendmsg() 467 call to be used in conjunction with cmsg ancillary data to 468 indicate the priority level of the data. For normal applications 469 this capability would be of little use because it would most 470 likely result in corruption of the data stream, but it is useful 471 with Minion because the RECOBS encoding is robust against message 472 insertion at arbitrary byte boundaries. An alternative way to 473 achieve a similar effect is, instead of buffering data in the 474 kernel, to keep the data in the user-space library for as long as 475 possible. When the TCP congestion window and/or receive window 476 rules allow more data to be sent, the kernel generates some kind 477 of upcall (e.g., a kevent notification) to the user-space library 478 informing it of the ability to transmit, and the user-space 479 library responds by selecting which particular block of data to 480 hand to the kernel next. 482 Immediate Receive 483 Normal TCP APIs deliver data only in TCP sequence number order. 484 The addition of support for new cmsg ancillary data in the 485 recvmsg() call allows the user-space library to request *any* 486 available data, not only in-order data. The cmsg ancillary data 487 returned from the recvmsg() call indicates to the user-space 488 library where in the TCP sequence space this particular block of 489 data lies. 491 Integrated Receive Window 492 Normal TCP APIs raise the receive window any time data is read out 493 of the kernel into user space. The addition of new cmsg ancillary 494 data in the recvmsg() call allows the user-space library to 495 request that the kernel return received data *without* reflecting 496 this in its receive window calculation. After the client 497 application has consumed the message data from the user-space 498 Minion library, the Minion library makes a subsequent recvmsg() 499 call with appropriate cmsg ancillary data to inform the kernel how 500 many bytes to add back into its receive window. In essence, the 501 receive window boundary is stretched outside the kernel to account 502 for data held by *both* the kernel *and* the user-space Minion 503 library. 505 These optional kernel extensions are a key part of what makes Minion 506 compelling. Minion can be adopted today by any application, using 507 Minion as a purely user-space library. Such an application performs 508 as well as any application can when it is built on top of standard 509 TCP. However, unlike an application built on top of standard TCP, 510 Minion offers the promise of future kernel support for even better 511 performance. Any given application with its own application-specific 512 protocol is unlikely to receive special kernel support to make just 513 that one application work better. But when many applications all use 514 the Minion protocol, it then becomes reasonable to add kernel support 515 to improve all of those applications. 517 8. IANA Considerations 519 No IANA actions are required by this document. 521 9. Security Considerations 523 No new security risks occur as a result of using this protocol. 525 10. Acknowledgements 527 Many thanks to Bryan Ford, Padma Bhooma and Anumita Biswas for their 528 contributions to the development of Minion. 530 11. References 532 11.1. Normative References 534 [COBS] Cheshire, S. and M. Baker, "Consistent Overhead Byte 535 Stuffing", September 1997, 536 . 538 [RFC0793] Postel, J., "Transmission Control Protocol", STD 7, RFC 539 793, September 1981. 541 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 542 Requirement Levels", BCP 14, RFC 2119, March 1997. 544 [RFC6347] Rescorla, E. and N. Modadugu, "Datagram Transport Layer 545 Security Version 1.2", RFC 6347, January 2012. 547 [minserv] Iyengar, J., "Minion - Service Model and Conceptual API", 548 draft-iyengar-minion-concept-00 (work in progress), June 549 2013. 551 11.2. Informative References 553 [RFC0768] Postel, J., "User Datagram Protocol", STD 6, RFC 768, 554 August 1980. 556 Authors' Addresses 557 Janardhan Iyengar 558 Franklin and Marshall College 559 Mathematics and Computer Science 560 PO Box 3003 561 Lancaster, Pennsylvania 17604-3003 562 USA 564 Phone: +1 717 358 4774 565 Email: janardhan.iyengar@fandm.edu 567 Stuart Cheshire 568 Apple Inc. 569 1 Infinite Loop 570 Cupertino, California 95014 571 USA 573 Phone: +1 408 974 3207 574 Email: cheshire@apple.com 576 Josh Graessley 577 Apple Inc. 578 1 Infinite Loop 579 Cupertino, California 95014 580 USA 582 Phone: +1 408 974 5710 583 Email: jgraessley@apple.com