14. Maximum Packet Size
A DCCP implementation MUST maintain the maximum packet size (MPS) allowed for each active DCCP session. The MPS is influenced by the maximum packet size allowed by the current congestion control mechanism (CCMPS), the maximum packet size supported by the path's links (PMTU, the Path Maximum Transmission Unit) [RFC1191], and the lengths of the IP and DCCP headers.
A DCCP application interface SHOULD let the application discover DCCP's current MPS. Generally, the DCCP implementation will refuse to send any packet bigger than the MPS, returning an appropriate error to the application. A DCCP interface MAY allow applications to request fragmentation for packets larger than PMTU, but not larger than CCMPS. (Packets larger than CCMPS MUST be rejected in any case.) Fragmentation SHOULD NOT be the default, since it decreases robustness: an entire packet is discarded if even one of its fragments is lost. Applications can usually get better error tolerance by producing packets smaller than the PMTU. The MPS reported to the application SHOULD be influenced by the size expected to be required for DCCP headers and options. If the application provides data that, when combined with the options the DCCP implementation would like to include, would exceed the MPS, the implementation should either send the options on a separate packet (such as a DCCP-Ack) or lower the MPS, drop the data, and return an appropriate error to the application.14.1. Measuring PMTU
Each DCCP endpoint MUST keep track of the current PMTU for each connection, except that this is not required for IPv4 connections whose applications have requested fragmentation. The PMTU SHOULD be initialized from the interface MTU that will be used to send packets. The MPS will be initialized with the minimum of the PMTU and the CCMPS, if any. Classical PMTU discovery uses unfragmentable packets. In IPv4, these packets have the IP Don't Fragment (DF) bit set; in IPv6, all packets are unfragmentable once emitted by an end host. As specified in [RFC1191], when a router receives a packet with DF set that is larger than the next link's MTU, it sends an ICMP Destination Unreachable message back to the source whose Code indicates that an unfragmentable packet was too large to forward (a "Datagram Too Big" message). When a DCCP implementation receives a Datagram Too Big message, it decreases its PMTU to the Next-Hop MTU value given in the ICMP message. If the MTU given in the message is zero, the sender chooses a value for PMTU using the algorithm described in [RFC1191], Section 7. If the MTU given in the message is greater than the current PMTU, the Datagram Too Big message is ignored, as described in [RFC1191]. (We are aware that this may cause problems for DCCP endpoints behind certain firewalls.) A DCCP implementation may allow the application occasionally to request that PMTU discovery be performed again. This will reset the PMTU to the outgoing interface's MTU. Such requests SHOULD be rate limited, to one per two seconds, for example.
A DCCP sender MAY treat the reception of an ICMP Datagram Too Big message as an indication that the packet being reported was not lost due to congestion, and so for the purposes of congestion control it MAY ignore the DCCP receiver's indication that this packet did not arrive. However, if this is done, then the DCCP sender MUST check the ECN bits of the IP header echoed in the ICMP message and only perform this optimization if these ECN bits indicate that the packet did not experience congestion prior to reaching the router whose link MTU it exceeded. A DCCP implementation SHOULD ensure, as far as possible, that ICMP Datagram Too Big messages were actually generated by routers, so that attackers cannot drive the PMTU down to a falsely small value. The simplest way to do this is to verify that the Sequence Number on the ICMP error's encapsulated header corresponds to a Sequence Number that the implementation recently sent. (According to current specifications, routers should return the full DCCP header and payload up to a maximum of 576 bytes [RFC1812] or the minimum IPv6 MTU [RFC2463], although they are not required to return more than 64 bits [RFC792]. Any amount greater than 128 bits will include the Sequence Number.) ICMP Datagram Too Big messages with incorrect or missing Sequence Numbers may be ignored, or the DCCP implementation may lower the PMTU only temporarily in response. If more than three odd Datagram Too Big messages are received and the other DCCP endpoint reports more than three lost packets, however, the DCCP implementation SHOULD assume the presence of a confused router and either obey the ICMP messages' PMTU or (on IPv4 networks) switch to allowing fragmentation. DCCP also allows upward probing of the PMTU [PMTUD], where the DCCP endpoint begins by sending small packets with DF set and then gradually increases the packet size until a packet is lost. This mechanism does not require any ICMP error processing. DCCP-Sync packets are the best choice for upward probing, since DCCP-Sync probes do not risk application data loss. The DCCP implementation inserts arbitrary data into the DCCP-Sync application area, padding the packet to the right length. Since every valid DCCP-Sync generates an immediate DCCP-SyncAck in response, the endpoint will have a pretty good idea of when a probe is lost.14.2. Sender Behavior
A DCCP sender SHOULD send every packet as unfragmentable, as described above, with the following exceptions. o On IPv4 connections whose applications have requested fragmentation, the sender SHOULD send packets with the DF bit not set.
o On IPv6 connections whose applications have requested fragmentation, the sender SHOULD use fragmentation extension headers to fragment packets larger than PMTU into suitably-sized chunks. (Those chunks are, of course, unfragmentable.) o It is undesirable for PMTU discovery to occur on the initial connection setup handshake, as the connection setup process may not be representative of packet sizes used during the connection, and performing MTU discovery on the initial handshake might unnecessarily delay connection establishment. Thus, DCCP-Request and DCCP-Response packets SHOULD be sent as fragmentable. In addition, DCCP-Reset packets SHOULD be sent as fragmentable, although typically these would be small enough to not be a problem. For IPv4 connections, these packets SHOULD be sent with the DF bit not set; for IPv6 connections, they SHOULD be preemptively fragmented to a size not larger than the relevant interface MTU. If the DCCP implementation has decreased the PMTU, the sending application has not requested fragmentation, and the sending application attempts to send a packet larger than the new MPS, the API MUST refuse to send the packet and return an appropriate error to the application. The application should then use the API to query the new value of MPS. The kernel might have some packets buffered for transmission that are smaller than the old MPS but larger than the new MPS. It MAY send these packets as fragmentable, or it MAY discard these packets; it MUST NOT send them as unfragmentable.15. Forward Compatibility
Future versions of DCCP may add new options and features. A few simple guidelines will let extended DCCPs interoperate with normal DCCPs. o DCCP processors MUST NOT act punitively towards options and features they do not understand. For example, DCCP processors MUST NOT reset the connection if some field marked Reserved in this specification is non-zero; if some unknown option is present; or if some feature negotiation option mentions an unknown feature. Instead, DCCP processors MUST ignore these events. The Mandatory option is the single exception: if Mandatory precedes some unknown option or feature, the connection MUST be reset. o DCCP processors MUST anticipate the possibility of unknown feature values, which might occur as part of a negotiation for a known feature. For server-priority features, unknown values are handled as a matter of course: since the non-extended DCCP's priority list will not contain unknown values, the result of the negotiation
cannot be an unknown value. A DCCP MUST respond with an empty Confirm option if it is assigned an unacceptable value for some non-negotiable feature. o Each DCCP extension SHOULD be controlled by some feature. The default value of this feature SHOULD correspond to "extension not available". If an extended DCCP wants to use the extension, it SHOULD attempt to change the feature's value using a Change L or Change R option. Any non-extended DCCP will ignore the option, thus leaving the feature value at its default, "extension not available". Section 19 lists DCCP assigned numbers reserved for experimental and testing purposes.16. Middlebox Considerations
This section describes properties of DCCP that firewalls, network address translators, and other middleboxes should consider, including parts of the packet that middleboxes should not change. The intent is to draw attention to aspects of DCCP that may be useful, or dangerous, for middleboxes, or that differ significantly from TCP. The Service Code field in DCCP-Request packets provides information that may be useful for stateful middleboxes. With Service Code, a middlebox can tell what protocol a connection will use without relying on port numbers. Middleboxes can disallow connections that attempt to access unexpected services by sending a DCCP-Reset with Reset Code 8, "Bad Service Code". Middleboxes should not modify the Service Code unless they are really changing the service a connection is accessing. The Source and Destination Port fields are in the same packet locations as the corresponding fields in TCP and UDP, which may simplify some middlebox implementations. The forward compatibility considerations in Section 15 apply to middleboxes as well. In particular, middleboxes generally shouldn't act punitively towards options and features they do not understand. Modifying DCCP Sequence Numbers and Acknowledgement Numbers is more tedious and dangerous than modifying TCP sequence numbers. A middlebox that added packets to or removed packets from a DCCP connection would have to modify acknowledgement options, such as Ack Vector, and CCID-specific options, such as TFRC's Loss Intervals, at minimum. On ECN-capable connections, the middlebox would have to keep track of ECN Nonce information for packets it introduced or removed, so that the relevant acknowledgement options continued to
have correct ECN Nonce Echoes, or risk the connection being reset for "Aggression Penalty". We therefore recommend that middleboxes not modify packet streams by adding or removing packets. Note that there is less need to modify DCCP's per-packet sequence numbers than to modify TCP's per-byte sequence numbers; for example, a middlebox can change the contents of a packet without changing its sequence number. (In TCP, sequence number modification is required to support protocols like FTP that carry variable-length addresses in the data stream. If such an application were deployed over DCCP, middleboxes would simply grow or shrink the relevant packets as necessary without changing their sequence numbers. This might involve fragmenting the packet.) Middleboxes may, of course, reset connections in progress. Clearly, this requires inserting a packet into one or both packet streams, but the difficult issues do not arise. DCCP is somewhat unfriendly to "connection splicing" [SHHP00], in which clients' connection attempts are intercepted, but possibly later "spliced in" to external server connections via sequence number manipulations. A connection splicer at minimum would have to ensure that the spliced connections agreed on all relevant feature values, which might take some renegotiation. The contents of this section should not be interpreted as a wholesale endorsement of stateful middleboxes.17. Relations to Other Specifications
17.1. RTP
The Real-Time Transport Protocol, RTP [RFC3550], is currently used over UDP by many of DCCP's target applications (for instance, streaming media). Therefore, it is important to examine the relationship between DCCP and RTP and, in particular, the question of whether any changes in RTP are necessary or desirable when it is layered over DCCP instead of UDP. There are two potential sources of overhead in the RTP-over-DCCP combination: duplicated acknowledgement information and duplicated sequence numbers. Together, these sources of overhead add slightly more than 4 bytes per packet relative to RTP-over-UDP, and eliminating the redundancy would not reduce the overhead. First, consider acknowledgements. Both RTP and DCCP report feedback about loss rates to data senders, via RTP Control Protocol Sender and Receiver Reports (RTCP SR/RR packets) and via DCCP acknowledgement
options. These feedback mechanisms are potentially redundant. However, RTCP SR/RR packets contain information not present in DCCP acknowledgements, such as "interarrival jitter", and DCCP's acknowledgements contain information not transmitted by RTCP, such as the ECN Nonce Echo. Neither feedback mechanism makes the other redundant. Sending both types of feedback need not be particularly costly either. RTCP reports may be sent relatively infrequently: once every 5 seconds on average, for low-bandwidth flows. In DCCP, some feedback mechanisms are expensive -- Ack Vector, for example, is frequent and verbose -- but others are relatively cheap: CCID 3 (TFRC) acknowledgements take between 16 and 32 bytes of options sent once per round-trip time. (Reporting less frequently than once per RTT would make congestion control less responsive to loss.) We therefore conclude that acknowledgement overhead in RTP-over-DCCP need not be significantly higher than for RTP-over-UDP, at least for CCID 3. One clear redundancy can be addressed at the application level. The verbose packet-by-packet loss reports sent in RTCP Extended Reports Loss RLE Blocks [RFC3611] can be derived from DCCP's Ack Vector options. (The converse is not true, since Loss RLE Blocks contain no ECN information.) Since DCCP implementations should provide an API for application access to Ack Vector information, RTP-over-DCCP applications might request either DCCP Ack Vectors or RTCP Extended Report Loss RLE Blocks, but not both. Now consider sequence number redundancy on data packets. The embedded RTP header contains a 16-bit RTP sequence number. Most data packets will use the DCCP-Data type; DCCP-DataAck and DCCP-Ack packets need not usually be sent. The DCCP-Data header is 12 bytes long without options, including a 24-bit sequence number. This is 4 bytes more than a UDP header. Any options required on data packets would add further overhead, although many CCIDs (for instance, CCID 3, TFRC) don't require options on most data packets. The DCCP sequence number cannot be inferred from the RTP sequence number since it increments on non-data packets as well as data packets. The RTP sequence number cannot be inferred from the DCCP sequence number either [RFC3550]. Furthermore, removing RTP's sequence number would not save any header space because of alignment issues. We therefore recommend that RTP transmitted over DCCP use the same headers currently defined. The 4 byte header cost is a reasonable tradeoff for DCCP's congestion control features and access to ECN. Truly bandwidth-starved endpoints should use some header compression scheme.
17.2. Congestion Manager and Multiplexing
Since DCCP doesn't provide reliable, ordered delivery, multiple application sub-flows may be multiplexed over a single DCCP connection with no inherent performance penalty. Thus, there is no need for DCCP to provide built-in support for multiple sub-flows. This differs from SCTP [RFC2960]. Some applications might want to share congestion control state among multiple DCCP flows that share the same source and destination addresses. This functionality could be provided by the Congestion Manager [RFC3124], a generic multiplexing facility. However, the CM would not fully support DCCP without change; it does not gracefully handle multiple congestion control mechanisms, for example.18. Security Considerations
DCCP does not provide cryptographic security guarantees. Applications desiring cryptographic security services (integrity, authentication, confidentiality, access control, and anti-replay protection) should use IPsec or end-to-end security of some kind; Secure RTP is one candidate protocol [RFC3711]. Nevertheless, DCCP is intended to protect against some classes of attackers: Attackers cannot hijack a DCCP connection (close the connection unexpectedly, or cause attacker data to be accepted by an endpoint as if it came from the sender) unless they can guess valid sequence numbers. Thus, as long as endpoints choose initial sequence numbers well, a DCCP attacker must snoop on data packets to get any reasonable probability of success. Sequence number validity checks provide this guarantee. Section 7.5.5 describes sequence number security further. This security property only holds assuming that DCCP's random numbers are chosen according to the guidelines in [RFC4086]. DCCP also provides mechanisms to limit the potential impact of some denial-of-service attacks. These mechanisms include Init Cookie (Section 8.1.4), the DCCP-CloseReq packet (Section 5.5), the Application Not Listening Drop Code (Section 11.7.2), limitations on the processing of options that might cause connection reset (Section 7.5.5), limitations on the processing of some ICMP messages (Section 14.1), and various rate limits, which let servers avoid extensive computation or packet generation (Sections 7.5.3, 8.1.3, and others). DCCP provides no protection against attackers that can snoop on data packets.
18.1. Security Considerations for Partial Checksums
The partial checksum facility has a separate security impact, particularly in its interaction with authentication and encryption mechanisms. The impact is the same in DCCP as in the UDP-Lite protocol, and what follows was adapted from the corresponding text in the UDP-Lite specification [RFC3828]. When a DCCP packet's Checksum Coverage field is not zero, the uncovered portion of a packet may change in transit. This is contrary to the idea behind most authentication mechanisms: authentication succeeds if the packet has not changed in transit. Unless authentication mechanisms that operate only on the sensitive part of packets are developed and used, authentication will always fail for partially-checksummed DCCP packets whose uncovered part has been damaged. The IPsec integrity check (Encapsulation Security Protocol, ESP, or Authentication Header, AH) is applied (at least) to the entire IP packet payload. Corruption of any bit within that area will then result in the IP receiver's discarding a DCCP packet, even if the corruption happened in an uncovered part of the DCCP application data. When IPsec is used with ESP payload encryption, a link can not determine the specific transport protocol of a packet being forwarded by inspecting the IP packet payload. In this case, the link MUST provide a standard integrity check covering the entire IP packet and payload. DCCP partial checksums provide no benefit in this case. Encryption (e.g., at the transport or application levels) may be used. Note that omitting an integrity check can, under certain circumstances, compromise confidentiality [B98]. If a few bits of an encrypted packet are damaged, the decryption transform will typically spread errors so that the packet becomes too damaged to be of use. Many encryption transforms today exhibit this behavior. There exist encryption transforms, stream ciphers, that do not cause error propagation. Proper use of stream ciphers can be quite difficult, especially when authentication checking is omitted [BB01]. In particular, an attacker can cause predictable changes to the ultimate plaintext, even without being able to decrypt the ciphertext.
19. IANA Considerations
IANA has assigned IP Protocol Number 33 to DCCP. DCCP introduces eight sets of numbers whose values should be allocated by IANA. We refer to allocation policies, such as Standards Action, outlined in [RFC2434], and most registries reserve some values for experimental and testing use [RFC3692]. In addition, DCCP requires that the IANA Port Numbers registry be opened for DCCP port registrations; Section 19.9 describes how. The IANA should feel free to contact the DCCP Expert Reviewer with questions on any registry, regardless of the registry policy, for clarification or if there is a problem with a request.19.1. Packet Types Registry
Each entry in the DCCP Packet Types registry contains a packet type, which is a number in the range 0-15; a packet type name, such as DCCP-Request; and a reference to the RFC defining the packet type. The registry is initially populated using the values in Table 1 (Section 5.1). This document allocates packet types 0-9, and packet type 14 is permanently reserved for experimental and testing use. Packet types 10-13 and 15 are currently reserved and should be allocated with the Standards Action policy, which requires IESG review and approval and standards-track IETF RFC publication.19.2. Reset Codes Registry
Each entry in the DCCP Reset Codes registry contains a Reset Code, which is a number in the range 0-255; a short description of the Reset Code, such as "No Connection"; and a reference to the RFC defining the Reset Code. The registry is initially populated using the values in Table 2 (Section 5.6). This document allocates Reset Codes 0-11, and Reset Codes 120-126 are permanently reserved for experimental and testing use. Reset Codes 12-119 and 127 are currently reserved and should be allocated with the IETF Consensus policy, requiring an IETF RFC publication (standards track or not) with IESG review and approval. Reset Codes 128-255 are permanently reserved for CCID-specific registries; each CCID Profile document describes how the corresponding registry is managed.19.3. Option Types Registry
Each entry in the DCCP option types registry contains an option type, which is a number in the range 0-255; the name of the option, such as "Slow Receiver"; and a reference to the RFC defining the option type. The registry is initially populated using the values in Table 3 (Section 5.8). This document allocates option types 0-2 and 32-44,
and option types 31 and 120-126 are permanently reserved for experimental and testing use. Option types 3-30, 45-119, and 127 are currently reserved and should be allocated with the IETF Consensus policy, requiring an IETF RFC publication (standards track or not) with IESG review and approval. Option types 128-255 are permanently reserved for CCID-specific registries; each CCID Profile document describes how the corresponding registry is managed.19.4. Feature Numbers Registry
Each entry in the DCCP feature numbers registry contains a feature number, which is a number in the range 0-255; the name of the feature, such as "ECN Incapable"; and a reference to the RFC defining the feature number. The registry is initially populated using the values in Table 4 (Section 6). This document allocates feature numbers 0-9, and feature numbers 120-126 are permanently reserved for experimental and testing use. Feature numbers 10-119 and 127 are currently reserved and should be allocated with the IETF Consensus policy, requiring an IETF RFC publication (standards track or not) with IESG review and approval. Feature numbers 128-255 are permanently reserved for CCID-specific registries; each CCID Profile document describes how the corresponding registry is managed.19.5. Congestion Control Identifiers Registry
Each entry in the DCCP Congestion Control Identifiers (CCIDs) registry contains a CCID, which is a number in the range 0-255; the name of the CCID, such as "TCP-like Congestion Control"; and a reference to the RFC defining the CCID. The registry is initially populated using the values in Table 5 (Section 10). CCIDs 2 and 3 are allocated by concurrently published profiles, and CCIDs 248-254 are permanently reserved for experimental and testing use. CCIDs 0, 1, 4-247, and 255 are currently reserved and should be allocated with the IETF Consensus policy, requiring an IETF RFC publication (standards track or not) with IESG review and approval.19.6. Ack Vector States Registry
Each entry in the DCCP Ack Vector States registry contains an Ack Vector State, which is a number in the range 0-3; the name of the State, such as "Received ECN Marked"; and a reference to the RFC defining the State. The registry is initially populated using the values in Table 6 (Section 11.4). This document allocates States 0, 1, and 3. State 2 is currently reserved and should be allocated with the Standards Action policy, which requires IESG review and approval and standards-track IETF RFC publication.
19.7. Drop Codes Registry
Each entry in the DCCP Drop Codes registry contains a Data Dropped Drop Code, which is a number in the range 0-7; the name of the Drop Code, such as "Application Not Listening"; and a reference to the RFC defining the Drop Code. The registry is initially populated using the values in Table 7 (Section 11.7). This document allocates Drop Codes 0-3 and 7. Drop Codes 4-6 are currently reserved, and should be allocated with the Standards Action policy, which requires IESG review and approval and standards-track IETF RFC publication.19.8. Service Codes Registry
Each entry in the Service Codes registry contains a Service Code, which is a number in the range 0-4294967294; a short English description of the intended service; and an optional reference to an RFC or other publicly available specification defining the Service Code. The registry should list the Service Code's numeric value as a decimal number. When the Service Code may be represented in "SC:" format according to the rules in Section 8.1.2, the registry should also show the corresponding ASCII interpretation of the Service Code minus the "SC:" prefix. Thus, the number 1717858426 would additionally appear as "fdpz". Service Codes are not DCCP-specific. Service Code 0 is permanently reserved (it represents the absence of a meaningful Service Code), and Service Codes 1056964608-1073741823 (high byte ASCII "?") are reserved for Private Use. Note that 4294967295 is not a valid Service Code. Most of the remaining Service Codes are allocated First Come First Served, with no RFC publication required; exceptions are listed in Section 8.1.2. This document allocates a single Service Code, 1145656131 ("DISC"). This corresponds to the discard service, which discards all data sent to the service and sends no data in reply.19.9. Port Numbers Registry
DCCP services may use contact port numbers to provide service to unknown callers, as in TCP and UDP. IANA is therefore requested to open the existing Port Numbers registry for DCCP using the following rules, which we intend to mesh well with existing Port Numbers registration procedures. Port numbers are divided into three ranges. The Well Known Ports are those from 0 through 1023, the Registered Ports are those from 1024 through 49151, and the Dynamic and/or Private Ports are those from 49152 through 65535. Well Known and Registered Ports are intended for use by server applications that desire a default contact point on a system. On most systems, Well Known Ports can only be used by system (or root) processes or by programs executed by privileged
users, while Registered Ports can be used by ordinary user processes or programs executed by ordinary users. Dynamic and/or Private Ports are intended for temporary use, including client-side ports, out-of- band negotiated ports, and application testing prior to registration of a dedicated port; they MUST NOT be registered. The Port Numbers registry should accept registrations for DCCP ports in the Well Known Ports and Registered Ports ranges. Well Known and Registered Ports SHOULD NOT be used without registration. Although in some cases -- such as porting an application from UDP to DCCP -- it may seem natural to use a DCCP port before registration completes, we emphasize that IANA will not guarantee registration of particular Well Known and Registered Ports. Registrations should be requested as early as possible. Each port registration SHALL include the following information: o A short port name, consisting entirely of letters (A-Z and a-z), digits (0-9), and punctuation characters from "-_+./*" (not including the quotes). o The port number that is requested to be registered. o A short English phrase describing the port's purpose. This MUST include one or more space-separated textual Service Code descriptors naming the port's corresponding Service Codes (see Section 8.1.2). o Name and contact information for the person or entity performing the registration, and possibly a reference to a document defining the port's use. Registrations coming from IETF working groups need only name the working group, but indicating a contact person is recommended. Registrants are encouraged to follow these guidelines when submitting a registration. o A port name SHOULD NOT be registered for more than one DCCP port number. o A port name registered for UDP MAY be registered for DCCP as well. Any such registration SHOULD use the same port number as the existing UDP registration. o Concrete intent to use a port SHOULD precede port registration. For example, existing UDP ports SHOULD NOT be registered in advance of any intent to use those ports for DCCP.
o A port name generally associated with TCP and/or SCTP SHOULD NOT be registered for DCCP, since that port name implies reliable transport. For example, we discourage registration of any "http" port for DCCP. However, if such a registration makes sense (that is, if there is concrete intent to use such a port), the DCCP registration SHOULD use the same port number as the existing registration. o Multiple DCCP registrations for the same port number are allowed as long as the registrations' Service Codes do not overlap. This document registers the following port. (This should be considered a model registration.) discard 9/dccp Discard SC:DISC # IETF dccp WG, Eddie Kohler <kohler@cs.ucla.edu>, [RFC4340] The discard service, which accepts DCCP connections on port 9, discards all incoming application data and sends no data in response. Thus, DCCP's discard port is analogous to TCP's discard port, and might be used to check the health of a DCCP stack.20. Thanks
Thanks to Jitendra Padhye for his help with early versions of this specification. Thanks to Junwen Lai and Arun Venkataramani, who, as interns at ICIR, built a prototype DCCP implementation. In particular, Junwen Lai recommended that the old feature negotiation mechanism be scrapped and co-designed the current mechanism. Arun Venkataramani's feedback improved Appendix A. We thank the staff and interns of ICIR and, formerly, ACIRI, the members of the End-to-End Research Group, and the members of the Transport Area Working Group for their feedback on DCCP. We especially thank the DCCP expert reviewers Greg Minshall, Eric Rescorla, and Magnus Westerlund for detailed written comments and problem spotting, and Rob Austein and Steve Bellovin for verbal comments and written notes. We also especially thank Aaron Falk, the working group chair during the development of this specification. We also thank those who provided comments and suggestions via the DCCP BOF, Working Group, and mailing lists, including Damon Lanphear, Patrick McManus, Colin Perkins, Sara Karlberg, Kevin Lai, Bernard Aboba, Youngsoo Choi, Pengfei Di, Dan Duchamp, Lars Eggert, Gorry Fairhurst, Derek Fawcus, David Timothy Fleeman, John Loughney, Ghyslain Pelletier, Hagen Paul Pfeifer, Tom Phelan, Stanislav
Shalunov, Somsak Vanit-Anunchai, David Vos, Yufei Wang, and Michael Welzl. In particular, Colin Perkins provided extensive, detailed feedback, Michael Welzl suggested the Data Checksum option, Gorry Fairhurst provided extensive feedback on various checksum issues, and Somsak Vanit-Anunchai, Jonathan Billington, and Tul Kongprakaiwoot's Colored Petri Net model [VBK05] discovered several problems with message exchange.
A. Appendix: Ack Vector Implementation Notes
This appendix discusses particulars of DCCP acknowledgement handling in the context of an abstract implementation for Ack Vector. It is informative and not normative. The first part of our implementation runs at the HC-Receiver, and therefore acknowledges data packets. It generates Ack Vector options. The implementation has the following characteristics: o At most one byte of state per acknowledged packet. o O(1) time to update that state when a new packet arrives (normal case). o Cumulative acknowledgements. o Quick removal of old state. The basic data structure is a circular buffer containing information about acknowledged packets. Each byte in this buffer contains a state and run length; the state can be 0 (packet received), 1 (packet ECN marked), or 3 (packet not yet received). The buffer grows from right to left. The implementation maintains five variables, aside from the buffer contents: o "buf_head" and "buf_tail", which mark the live portion of the buffer. o "buf_ackno", the Acknowledgement Number of the most recent packet acknowledged in the buffer. This corresponds to the "head" pointer. o "buf_nonce", the one-bit sum (exclusive-or, or parity) of the ECN Nonces received on all packets acknowledged by the buffer with State 0. We draw acknowledgement buffers like this: +---------------------------------------------------------------+ |S,L|S,L|S,L|S,L| | | | |S,L|S,L|S,L|S,L|S,L|S,L|S,L|S,L| +---------------------------------------------------------------+ ^ ^ buf_tail buf_head, buf_ackno = A buf_nonce = E <=== buf_head and buf_tail move this way <===
Each "S,L" represents a State/Run length byte. We will draw these buffers showing only their live portion and will add an annotation showing the Acknowledgement Number for the last live byte in the buffer. For example: +-----------------------------------------------+ A |S,L|S,L|S,L|S,L|S,L|S,L|S,L|S,L|S,L|S,L|S,L|S,L| T BN[E] +-----------------------------------------------+ Here, buf_nonce equals E and buf_ackno equals A. We will use this buffer as a running example. +---------------------------+ 10 |0,0|3,0|3,0|3,0|0,4|1,0|0,0| 0 BN[1] [Example Buffer] +---------------------------+ In concrete terms, its meaning is as follows: Packet 10 was received. (The head of the buffer has sequence number 10, state 0, and run length 0.) Packets 9, 8, and 7 have not yet been received. (The three bytes preceding the head each have state 3 and run length 0.) Packets 6, 5, 4, 3, and 2 were received. Packet 1 was ECN marked. Packet 0 was received. The one-bit sum of the ECN Nonces on packets 10, 6, 5, 4, 3, 2, and 0 equals 1. Additionally, the HC-Receiver must keep some information about the Ack Vectors it has recently sent. For each packet sent carrying an Ack Vector, it remembers four variables: o "ack_seqno", the Sequence Number used for the packet. This is an HC-Receiver sequence number. o "ack_ptr", the value of buf_head at the time of acknowledgement. o "ack_runlen", the run length stored in the byte of buffer data at buf_head at the time of acknowledgement.
o "ack_ackno", the Acknowledgement Number used for the packet. This is an HC-Sender sequence number. Since acknowledgements are cumulative, this single number completely specifies all necessary information about the packets acknowledged by this Ack Vector. o "ack_nonce", the one-bit sum of the ECN Nonces for all State 0 packets in the buffer from buf_head to ack_ackno, inclusive. Initially, this equals the Nonce Echo of the acknowledgement's Ack Vector (or, if the ack packet contained more than one Ack Vector, the exclusive-or of all the acknowledgement's Ack Vectors). It changes as information about old acknowledgements is removed (so ack_ptr and buf_head diverge) and as old packets arrive (so they change from State 3 or State 1 to State 0).A.1. Packet Arrival
This section describes how the HC-Receiver updates its acknowledgement buffer as packets arrive from the HC-Sender.A.1.1. New Packets
When a packet with Sequence Number greater than buf_ackno arrives, the HC-Receiver updates buf_head (by moving it to the left appropriately), buf_ackno (which is set to the new packet's Sequence Number), and possibly buf_nonce (if the packet arrived unmarked with ECN Nonce 1), in addition to the buffer itself. For example, if HC-Sender packet 11 arrived ECN marked, the Example Buffer above would enter this new state (changes are marked with stars): ** +***----------------------------+ 11 |1,0|0,0|3,0|3,0|3,0|0,4|1,0|0,0| 0 BN[1] ** +***----------------------------+ If the packet's state equals the state at the head of the buffer, the HC-Receiver may choose to increment its run length (up to the maximum). For example, if HC-Sender packet 11 arrived without ECN marking and with ECN Nonce 0, the Example Buffer might enter this state instead: ** +--*------------------------+ 11 |0,1|3,0|3,0|3,0|0,4|1,0|0,0| 0 BN[1] ** +--*------------------------+
Of course, the new packet's sequence number might not equal the expected sequence number. In this case, the HC-Receiver will enter the intervening packets as State 3. If several packets are missing, the HC-Receiver may prefer to enter multiple bytes with run length 0, rather than a single byte with a larger run length; this simplifies table updates if one of the missing packets arrives. For example, if HC-Sender packet 12 arrived with ECN Nonce 1, the Example Buffer would enter this state: ** +*******----------------------------+ * 12 |0,0|3,0|0,1|3,0|3,0|3,0|0,4|1,0|0,0| 0 BN[0] ** +*******----------------------------+ * Of course, the circular buffer may overflow when the HC-Sender is sending data at a very high rate, when the HC-Receiver's acknowledgements are not reaching the HC-Sender, or when the HC-Sender is forgetting to acknowledge those acks (so the HC-Receiver is unable to clean up old state). In this case, the HC-Receiver should either compress the buffer (by increasing run lengths when possible), transfer its state to a larger buffer, or, as a last resort, drop all received packets, without processing them at all, until its buffer shrinks again.A.1.2. Old Packets
When a packet with Sequence Number S <= buf_ackno arrives, the HC-Receiver will scan the table for the byte corresponding to S. (Indexing structures could reduce the complexity of this scan.) If S was previously lost (State 3), and it was stored in a byte with run length 0, the HC-Receiver can simply change the byte's state. For example, if HC-Sender packet 8 was received with ECN Nonce 0, the Example Buffer would enter this state: +--------*------------------+ 10 |0,0|3,0|0,0|3,0|0,4|1,0|0,0| 0 BN[1] +--------*------------------+ If S was not marked as lost, or if it was not contained in the table, the packet is probably a duplicate and should be ignored. (The new packet's ECN marking state might differ from the state in the buffer; Section 11.4.1 describes what is allowed then.) If S's buffer byte has a non-zero run length, then the buffer might need to be reshuffled to make space for one or two new bytes. The ack_nonce fields may also need manipulation when old packets arrive. In particular, when S transitions from State 3 or State 1 to State 0, and S had ECN Nonce 1, then the implementation should flip the value of ack_nonce for every acknowledgement with ack_ackno >= S.
It is impossible with this data structure to shift packets from State 0 to State 1, since the buffer doesn't store individual packets' ECN Nonces.A.2. Sending Acknowledgements
Whenever the HC-Receiver needs to generate an acknowledgement, the buffer's contents can simply be copied into one or more Ack Vector options. Copied Ack Vectors might not be maximally compressed; for example, the Example Buffer above contains three adjacent 3,0 bytes that could be combined into a single 3,2 byte. The HC-Receiver might, therefore, choose to compress the buffer in place before sending the option, or to compress the buffer while copying it; either operation is simple. Every acknowledgement sent by the HC-Receiver SHOULD include the entire state of the buffer. That is, acknowledgements are cumulative. If the acknowledgement fits in one Ack Vector, that Ack Vector's Nonce Echo simply equals buf_nonce. For multiple Ack Vectors, more care is required. The Ack Vectors should be split at points corresponding to previous acknowledgements, since the stored ack_nonce fields provide enough information to calculate correct Nonce Echoes. The implementation should therefore acknowledge data at least once per 253 bytes of buffer state. (Otherwise, there'd be no way to calculate a Nonce Echo.) For each acknowledgement it sends, the HC-Receiver will add an acknowledgement record. ack_seqno will equal the HC-Receiver sequence number it used for the ack packet; ack_ptr will equal buf_head; ack_runlen will equal the run length stored in the buffer's buf_head byte; ack_ackno will equal buf_ackno; and ack_nonce will equal buf_nonce.A.3. Clearing State
Some of the HC-Sender's packets will include acknowledgement numbers, which ack the HC-Receiver's acknowledgements. When such an ack is received, the HC-Receiver finds the acknowledgement record R with the appropriate ack_seqno and then does the following: o If the run length in the buffer's R.ack_ptr byte is greater than R.ack_runlen, then it decrements that run length by R.ack_runlen + 1 and sets buf_tail to R.ack_ptr. Otherwise, it sets buf_tail to R.ack_ptr + 1.
o If R.ack_nonce is 1, it flips buf_nonce, and the value of ack_nonce for every later ack record. o It throws away R and every preceding ack record. (The HC-Receiver may choose to keep some older information, in case a lost packet shows up late.) For example, say that the HC-Receiver storing the Example Buffer had sent two acknowledgements already: 1. ack_seqno = 59, ack_runlen = 1, ack_ackno = 3, ack_nonce = 1. 2. ack_seqno = 60, ack_runlen = 0, ack_ackno = 10, ack_nonce = 0. Say the HC-Receiver then received a DCCP-DataAck packet with Acknowledgement Number 59 from the HC-Sender. This informs the HC-Receiver that the HC-Sender received, and processed, all the information in HC-Receiver packet 59. This packet acknowledged HC-Sender packet 3, so the HC-Sender has now received HC-Receiver's acknowledgements for packets 0, 1, 2, and 3. The Example Buffer should enter this state: +------------------*+ * * 10 |0,0|3,0|3,0|3,0|0,2| 4 BN[0] +------------------*+ * * The tail byte's run length was adjusted, since packet 3 was in the middle of that byte. Since R.ack_nonce was 1, the buf_nonce field was flipped, as were the ack_nonce fields for later acknowledgements (here, the HC-Receiver Ack 60 record, not shown, has its ack_nonce flipped to 1). The HC-Receiver can also throw away stored information about HC-Receiver Ack 59 and any earlier acknowledgements. A careful implementation might try to ensure reasonable robustness to reordering. Suppose that the Example Buffer is as before, but that packet 9 now arrives, out of sequence. The buffer would enter this state: +----*----------------------+ 10 |0,0|0,0|3,0|3,0|0,4|1,0|0,0| 0 BN[1] +----*----------------------+ The danger is that the HC-Sender might acknowledge the HC-Receiver's previous acknowledgement (with sequence number 60), which says that Packet 9 was not received, before the HC-Receiver has a chance to send a new acknowledgement saying that Packet 9 actually was received. Therefore, when packet 9 arrived, the HC-Receiver might modify its acknowledgement record as follows:
1. ack_seqno = 59, ack_ackno = 3, ack_nonce = 1. 2. ack_seqno = 60, ack_ackno = 3, ack_nonce = 1. That is, Ack 60 is now treated like a duplicate of Ack 59. This would prevent the Tail pointer from moving past packet 9 until the HC-Receiver knows that the HC-Sender has seen an Ack Vector indicating that packet's arrival.A.4. Processing Acknowledgements
When the HC-Sender receives an acknowledgement, it generally cares about the number of packets that were dropped and/or ECN marked. It simply reads this off the Ack Vector. Additionally, it should check the ECN Nonce for correctness. (As described in Section 11.4.1, it may want to keep more detailed information about acknowledged packets in case packets change states between acknowledgements, or in case the application queries whether a packet arrived.) The HC-Sender must also acknowledge the HC-Receiver's acknowledgements so that the HC-Receiver can free old Ack Vector state. (Since Ack Vector acknowledgements are reliable, the HC-Receiver must maintain and resend Ack Vector information until it is sure that the HC-Sender has received that information.) A simple algorithm suffices: since Ack Vector acknowledgements are cumulative, a single acknowledgement number tells HC-Receiver how much ack information has arrived. Assuming that the HC-Receiver sends no data, the HC-Sender can ensure that at least once a round-trip time, it sends a DCCP-DataAck packet acknowledging the latest DCCP-Ack packet it has received. Of course, the HC-Sender only needs to acknowledge the HC-Receiver's acknowledgements if the HC-Sender is also sending data. If the HC-Sender is not sending data, then the HC-Receiver's Ack Vector state is stable, and there is no need to shrink it. The HC-Sender must watch for drops and ECN marks on received DCCP-Ack packets so that it can adjust the HC-Receiver's ack-sending rate in response to congestion, for example, with Ack Ratio. If the other half-connection is not quiescent -- that is, the HC-Receiver is sending data to the HC-Sender, possibly using another CCID -- then the acknowledgements on that half-connection are sufficient for the HC-Receiver to free its state.
B. Appendix: Partial Checksumming Design Motivation
A great deal of discussion has taken place regarding the utility of allowing a DCCP sender to restrict the checksum so that it does not cover the complete packet. This section attempts to capture some of the rationale behind specific details of DCCP design. Many of the applications that we envisage using DCCP are resilient to some degree of data loss, or they would typically have chosen a reliable transport. Some of these applications may also be resilient to data corruption -- some audio payloads, for example. These resilient applications might rather receive corrupted data than have DCCP drop corrupted packets. This is particularly because of congestion control: DCCP cannot tell the difference between packets dropped due to corruption and packets dropped due to congestion, and so it must reduce the transmission rate accordingly. This response may cause the connection to receive less bandwidth than it is due; corruption in some networking technologies is independent of, or at least not always correlated to, congestion. Therefore, corrupted packets do not need to cause as strong a reduction in transmission rate as the congestion response would dictate (as long as the DCCP header and options are not corrupt). Thus DCCP allows the checksum to cover all of the packet, just the DCCP header, or both the DCCP header and some number of bytes from the application data. If the application cannot tolerate any data corruption, then the checksum must cover the whole packet. If the application would prefer to tolerate some corruption rather than have the packet dropped, then it can set the checksum to cover only part of the packet (but always the DCCP header). In addition, if the application wishes to decouple checksumming of the DCCP header from checksumming of the application data, it may do so by including the Data Checksum option. This would allow DCCP to discard corrupted application data without mistaking the corruption for network congestion. Thus, from the application point of view, partial checksums seem to be a desirable feature. However, the usefulness of partial checksums depends on partially corrupted packets being delivered to the receiver. If the link-layer CRC always discards corrupted packets, then this will not happen, and so the usefulness of partial checksums would be restricted to corruption that occurred in routers and other places not covered by link CRCs. There does not appear to be consensus on how likely it is that future network links that suffer significant corruption will not cover the entire packet with a single strong CRC. DCCP makes it possible to tailor such links to the application, but it is difficult to predict if this will be compelling for future link technologies.
In addition, partial checksums do not co-exist well with IP-level authentication mechanisms such as IPsec AH, which cover the entire packet with a cryptographic hash. Thus, if cryptographic authentication mechanisms are required to co-exist with partial checksums, the authentication must be carried in the application data. A possible mode of usage would appear to be similar to that of Secure RTP. However, such "application-level" authentication does not protect the DCCP option negotiation and state machine from forged packets. An alternative would be to use IPsec ESP, and to use encryption to protect the DCCP headers against attack, while using the DCCP header validity checks to authenticate that the header is from someone who possessed the correct key. While this is resistant to replay (due to the DCCP sequence number), it is not by itself resistant to some forms of man-in-the-middle attacks because the application data is not tightly coupled to the packet header. Thus, an application-level authentication probably needs to be coupled with IPsec ESP or a similar mechanism to provide a reasonably complete security solution. The overhead of such a solution might be unacceptable for some applications that would otherwise wish to use partial checksums. On balance, the authors believe that DCCP partial checksums have the potential to enable some future uses that would otherwise be difficult. As the cost and complexity of supporting them is small, it seems worth including them at this time. It remains to be seen whether they are useful in practice.Normative References
[RFC793] Postel, J., "Transmission Control Protocol", STD 7, RFC 793, September 1981. [RFC1191] Mogul, J. and S. Deering, "Path MTU discovery", RFC 1191, November 1990. [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. [RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 2434, October 1998. [RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6 (IPv6) Specification", RFC 2460, December 1998. [RFC3168] Ramakrishnan, K., Floyd, S., and D. Black, "The Addition of Explicit Congestion Notification (ECN) to IP", RFC 3168, September 2001.
[RFC3309] Stone, J., Stewart, R., and D. Otis, "Stream Control Transmission Protocol (SCTP) Checksum Change", RFC 3309, September 2002. [RFC3692] Narten, T., "Assigning Experimental and Testing Numbers Considered Useful", BCP 82, RFC 3692, January 2004. [RFC3775] Johnson, D., Perkins, C., and J. Arkko, "Mobility Support in IPv6", RFC 3775, June 2004. [RFC3828] Larzon, L-A., Degermark, M., Pink, S., Jonsson, L-E., and G. Fairhurst, "The Lightweight User Datagram Protocol (UDP-Lite)", RFC 3828, July 2004.Informative References
[B98] Bellovin, S.M., "Cryptography and the Internet", CRYPTO '98 (LNCS 1462), pp 46-55, August 1988. [BB01] Bellovin, S.M. and M. Blaze, "Cryptographic Modes of Operation for the Internet", 2nd NIST Workshop on Modes of Operation, August 2001. [M85] Morris, R.T., "A Weakness in the 4.2BSD Unix TCP/IP Software", Computer Science Technical Report 117, AT&T Bell Laboratories, Murray Hill, NJ, February 1985. [PMTUD] Mathis, M. and J. Heffner, "Path MTU Discovery", Work in Progress, March 2006. [RFC792] Postel, J., "Internet Control Message Protocol", STD 5, RFC 792, September 1981. [RFC1812] Baker, F., "Requirements for IP Version 4 Routers", RFC 1812, June 1995. [RFC1948] Bellovin, S., "Defending Against Sequence Number Attacks", RFC 1948, May 1996. [RFC1982] Elz, R. and R. Bush, "Serial Number Arithmetic", RFC 1982, August 1996. [RFC2018] Mathis, M., Mahdavi, J., Floyd, S., and A. Romanow, "TCP Selective Acknowledgement Options", RFC 2018, October 1996.
[RFC2401] Kent, S. and R. Atkinson, "Security Architecture for the Internet Protocol", RFC 2401, November 1998. [RFC2463] Conta, A. and S. Deering, "Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification", RFC 2463, December 1998. [RFC2581] Allman, M., Paxson, V., and W. Stevens, "TCP Congestion Control", RFC 2581, April 1999. [RFC2960] Stewart, R., Xie, Q., Morneault, K., Sharp, C., Schwarzbauer, H., Taylor, T., Rytina, I., Kalla, M., Zhang, L., and V. Paxson, "Stream Control Transmission Protocol", RFC 2960, October 2000. [RFC3124] Balakrishnan, H. and S. Seshan, "The Congestion Manager", RFC 3124, June 2001. [RFC3360] Floyd, S., "Inappropriate TCP Resets Considered Harmful", BCP 60, RFC 3360, August 2002. [RFC3448] Handley, M., Floyd, S., Padhye, J., and J. Widmer, "TCP Friendly Rate Control (TFRC): Protocol Specification", RFC 3448, January 2003. [RFC3540] Spring, N., Wetherall, D., and D. Ely, "Robust Explicit Congestion Notification (ECN) Signaling with Nonces", RFC 3540, June 2003. [RFC3550] Schulzrinne, H., Casner, S., Frederick, R., and V. Jacobson, "RTP: A Transport Protocol for Real-Time Applications", STD 64, RFC 3550, July 2003. [RFC3611] Friedman, T., Caceres, R., and A. Clark, "RTP Control Protocol Extended Reports (RTCP XR)", RFC 3611, November 2003. [RFC3711] Baugher, M., McGrew, D., Naslund, M., Carrara, E., and K. Norrman, "The Secure Real-time Transport Protocol (SRTP)", RFC 3711, March 2004. [RFC3819] Karn, P., Bormann, C., Fairhurst, G., Grossman, D., Ludwig, R., Mahdavi, J., Montenegro, G., Touch, J., and L. Wood, "Advice for Internet Subnetwork Designers", BCP 89, RFC 3819, July 2004.
[RFC4086] Eastlake, D., 3rd, Schiller, J., and S. Crocker, "Randomness Requirements for Security", BCP 106, RFC 4086, June 2005. [RFC4341] Floyd, S. and E. Kohler, "Profile for Datagram Congestion Control Protocol (DCCP) Congestion Control ID 2: TCP-like Congestion Control", RFC 4341, March 2006. [RFC4342] Floyd, S., Kohler, E., and J. Padhye, "Profile for Datagram Congestion Control Protocol (DCCP) Congestion Control ID 3: TCP-Friendly Rate Control (TFRC)", RFC 4342, March 2006. [SHHP00] Spatscheck, O., Hansen, J.S., Hartman, J.H., and L.L. Peterson, "Optimizing TCP Forwarder Performance", IEEE/ACM Transactions on Networking 8(2):146-157, April 2000. [SYNCOOKIES] Bernstein, D.J., "SYN Cookies", http://cr.yp.to/syncookies.html, as of March 2006. [VBK05] Vanit-Anunchai, S., Billington, J., and T. Kongprakaiwoot, "Discovering Chatter and Incompleteness in the Datagram Congestion Control Protocol", FORTE 2005, pp 143-158, October 2005.
Authors' Addresses
Eddie Kohler 4531C Boelter Hall UCLA Computer Science Department Los Angeles, CA 90095 USA EMail: kohler@cs.ucla.edu Mark Handley Department of Computer Science University College London Gower Street London WC1E 6BT UK EMail: M.Handley@cs.ucl.ac.uk Sally Floyd ICSI Center for Internet Research 1947 Center Street, Suite 600 Berkeley, CA 94704 USA EMail: floyd@icir.org
Full Copyright Statement Copyright (C) The Internet Society (2006). This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights. This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Intellectual Property The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79. Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr. The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf- ipr@ietf.org. Acknowledgement Funding for the RFC Editor function is provided by the IETF Administrative Support Activity (IASA).