Network Working Group                                    H. Balakrishnan
Request for Comments: 3124                                       MIT LCS
Category: Standards Track                                      S. Seshan
                                                                     CMU
                                                               June 2001
        
Network Working Group                                    H. Balakrishnan
Request for Comments: 3124                                       MIT LCS
Category: Standards Track                                      S. Seshan
                                                                     CMU
                                                               June 2001
        

The Congestion Manager

拥塞管理器

Status of this Memo

本备忘录的状况

This document specifies an Internet standards track protocol for the Internet community, and requests discussion and suggestions for improvements. Please refer to the current edition of the "Internet Official Protocol Standards" (STD 1) for the standardization state and status of this protocol. Distribution of this memo is unlimited.

本文件规定了互联网社区的互联网标准跟踪协议,并要求进行讨论和提出改进建议。有关本协议的标准化状态和状态,请参考当前版本的“互联网官方协议标准”(STD 1)。本备忘录的分发不受限制。

Copyright Notice

版权公告

Copyright (C) The Internet Society (2001). All Rights Reserved.

版权所有(C)互联网协会(2001年)。版权所有。

Abstract

摘要

This document describes the Congestion Manager (CM), an end-system module that:

本文档介绍了拥塞管理器(CM),它是一个终端系统模块,用于:

(i) Enables an ensemble of multiple concurrent streams from a sender destined to the same receiver and sharing the same congestion properties to perform proper congestion avoidance and control, and

(i) 使来自发送方的多个并发流能够集成到同一接收方并共享相同的拥塞属性,以执行适当的拥塞避免和控制,以及

(ii) Allows applications to easily adapt to network congestion.

(ii)允许应用程序轻松适应网络拥塞。

1. Conventions used in this document:

1. 本文件中使用的约定:

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC-2119 [Bradner97].

本文件中的关键词“必须”、“不得”、“要求”、“应”、“不应”、“应”、“不应”、“建议”、“可”和“可选”应按照RFC-2119[Bradner97]中所述进行解释。

STREAM

流动

A group of packets that all share the same source and destination IP address, IP type-of-service, transport protocol, and source and destination transport-layer port numbers.

共享相同源和目标IP地址、服务IP类型、传输协议以及源和目标传输层端口号的一组数据包。

MACROFLOW

宏观流

A group of CM-enabled streams that all use the same congestion management and scheduling algorithms, and share congestion state information. Currently, streams destined to different receivers belong to different macroflows. Streams destined to the same receiver MAY belong to different macroflows. When the Congestion Manager is in use, streams that experience identical congestion behavior and use the same congestion control algorithm SHOULD belong to the same macroflow.

一组支持CM的流,它们都使用相同的拥塞管理和调度算法,并共享拥塞状态信息。目前,发送到不同接收器的流属于不同的宏流。发送到同一接收器的流可以属于不同的宏流。当使用拥塞管理器时,经历相同拥塞行为并使用相同拥塞控制算法的流应属于相同的宏流。

APPLICATION

应用

Any software module that uses the CM. This includes user-level applications such as Web servers or audio/video servers, as well as in-kernel protocols such as TCP [Postel81] that use the CM for congestion control.

使用CM的任何软件模块。这包括用户级应用程序,如Web服务器或音频/视频服务器,以及使用CM进行拥塞控制的内核协议,如TCP[Postel81]。

WELL-BEHAVED APPLICATION

性能良好的应用程序

An application that only transmits when allowed by the CM and accurately accounts for all data that it has sent to the receiver by informing the CM using the CM API.

一种应用程序,仅在CM允许的情况下进行传输,并通过使用CM API通知CM,准确说明发送给接收器的所有数据。

PATH MAXIMUM TRANSMISSION UNIT (PMTU)

路径最大传输单位(PMTU)

The size of the largest packet that the sender can transmit without it being fragmented en route to the receiver. It includes the sizes of all headers and data except the IP header.

发送方可以传输的最大数据包的大小,而不会在发送到接收方的过程中被分割。它包括除IP标头之外的所有标头和数据的大小。

CONGESTION WINDOW (cwnd)

拥塞窗口(cwnd)

A CM state variable that modulates the amount of outstanding data between sender and receiver.

一种CM状态变量,用于调节发送方和接收方之间未完成的数据量。

OUTSTANDING WINDOW (ownd)

突出窗口(自有)

The number of bytes that has been transmitted by the source, but not known to have been either received by the destination or lost in the network.

源已传输的字节数,但不知道目标已接收或在网络中丢失。

INITIAL WINDOW (IW)

初始窗口(IW)

The size of the sender's congestion window at the beginning of a macroflow.

宏流开始时发送方拥塞窗口的大小。

DATA TYPE SYNTAX

数据类型语法

We use "u64" for unsigned 64-bit, "u32" for unsigned 32-bit, "u16" for unsigned 16-bit, "u8" for unsigned 8-bit, "i32" for signed 32-bit, "i16" for signed 16-bit quantities, "float" for IEEE floating point values. The type "void" is used to indicate that no return value is expected from a call. Pointers are referred to using "*" syntax, following C language convention.

我们使用“u64”表示无符号64位,“u32”表示无符号32位,“u16”表示无符号16位,“u8”表示无符号8位,“i32”表示有符号32位,“i16”表示有符号16位量,“浮点”表示IEEE浮点值。类型“void”用于指示调用不需要返回值。指针使用“*”语法引用,遵循C语言约定。

We emphasize that all the API functions described in this document are "abstract" calls and that conformant CM implementations may differ in specific implementation details.

我们强调,本文档中描述的所有API函数都是“抽象”调用,一致的CM实现在具体实现细节上可能有所不同。

2. Introduction
2. 介绍

The framework described in this document integrates congestion management across all applications and transport protocols. The CM maintains congestion parameters (available aggregate and per-stream bandwidth, per-receiver round-trip times, etc.) and exports an API that enables applications to learn about network characteristics, pass information to the CM, share congestion information with each other, and schedule data transmissions. This document focuses on applications and transport protocols with their own independent per-byte or per-packet sequence number information, and does not require modifications to the receiver protocol stack. However, the receiving application must provide feedback to the sending application about received packets and losses, and the latter is expected to use the CM API to update CM state. This document does not address networks with reservations or service differentiation.

本文档中描述的框架集成了所有应用程序和传输协议中的拥塞管理。CM维护拥塞参数(可用聚合和每流带宽、每接收机往返时间等)并导出API,该API使应用程序能够了解网络特性、将信息传递给CM、彼此共享拥塞信息以及调度数据传输。本文档重点介绍具有各自独立的每字节或每包序列号信息的应用程序和传输协议,不需要修改接收器协议栈。但是,接收应用程序必须向发送应用程序提供有关接收到的数据包和丢失的反馈,并且后者应使用CM API来更新CM状态。本文档不涉及具有保留或服务差异的网络。

The CM is an end-system module that enables an ensemble of multiple concurrent streams to perform stable congestion avoidance and control, and allows applications to easily adapt their transmissions to prevailing network conditions. It integrates congestion management across all applications and transport protocols. It maintains congestion parameters (available aggregate and per-stream bandwidth, per-receiver round-trip times, etc.) and exports an API that enables applications to learn about network characteristics, pass information to the CM, share congestion information with each other, and schedule data transmissions. When the CM is used, all data transmissions subject to the CM must be done with the explicit consent of the CM via this API to ensure proper congestion behavior.

CM是一个终端系统模块,它使多个并发流的集合能够执行稳定的拥塞避免和控制,并允许应用程序轻松地使其传输适应当前的网络条件。它集成了所有应用程序和传输协议的拥塞管理。它维护拥塞参数(可用聚合和每流带宽、每接收机往返时间等),并导出API,使应用程序能够了解网络特性、将信息传递给CM、彼此共享拥塞信息以及调度数据传输。当使用CM时,所有受CM约束的数据传输必须在CM明确同意的情况下通过此API完成,以确保正确的拥塞行为。

Systems MAY choose to use CM, and if so they MUST follow this specification.

系统可以选择使用CM,如果是,则必须遵循本规范。

This document focuses on applications and networks where the following conditions hold:

本文档重点介绍满足以下条件的应用程序和网络:

1. Applications are well-behaved with their own independent per-byte or per-packet sequence number information, and use the CM API to update internal state in the CM.

1. 应用程序通过其各自独立的每字节或每包序列号信息表现良好,并使用CM API更新CM中的内部状态。

2. Networks are best-effort without service discrimination or reservations. In particular, it does not address situations where different streams between the same pair of hosts traverse paths with differing characteristics.

2. 网络是最大的努力,没有服务歧视或保留。特别是,它不解决同一对主机之间的不同流通过具有不同特征的路径的情况。

The Congestion Manager framework can be extended to support applications that do not provide their own feedback and to differentially-served networks. These extensions will be addressed in later documents.

拥塞管理器框架可以扩展,以支持不提供自身反馈的应用程序和不同服务的网络。这些扩展将在以后的文件中讨论。

The CM is motivated by two main goals:

构型管理有两个主要目标:

(i) Enable efficient multiplexing. Increasingly, the trend on the Internet is for unicast data senders (e.g., Web servers) to transmit heterogeneous types of data to receivers, ranging from unreliable real-time streaming content to reliable Web pages and applets. As a result, many logically different streams share the same path between sender and receiver. For the Internet to remain stable, each of these streams must incorporate control protocols that safely probe for spare bandwidth and react to congestion. Unfortunately, these concurrent streams typically compete with each other for network resources, rather than share them effectively. Furthermore, they do not learn from each other about the state of the network. Even if they each independently implement congestion control (e.g., a group of TCP connections each implementing the algorithms in [Jacobson88, Allman99]), the ensemble of streams tends to be more aggressive in the face of congestion than a single TCP connection implementing standard TCP congestion control and avoidance [Balakrishnan98].

(i) 启用高效多路复用。互联网上的趋势越来越倾向于单播数据发送者(例如,网络服务器)向接收者传输不同类型的数据,从不可靠的实时流媒体内容到可靠的网页和小程序。因此,许多逻辑上不同的流在发送方和接收方之间共享相同的路径。为了使互联网保持稳定,这些流中的每一个都必须包含安全探测空闲带宽并对拥塞作出反应的控制协议。不幸的是,这些并发流通常相互竞争网络资源,而不是有效地共享它们。此外,他们不会相互了解网络的状态。即使它们各自独立地实现拥塞控制(例如,一组TCP连接,每个连接实现[Jacobson88,Allman99]中的算法),流集合在拥塞面前往往比实现标准TCP拥塞控制和避免的单个TCP连接更具攻击性[Balakrishnan98]。

(ii) Enable application adaptation to congestion. Increasingly, popular real-time streaming applications run over UDP using their own user-level transport protocols for good application performance, but in most cases today do not adapt or react properly to network congestion. By implementing a stable control algorithm and exposing an adaptation API, the CM enables easy application adaptation to congestion. Applications adapt the data they transmit to the current network conditions.

(ii)使应用程序能够适应拥塞。越来越多的流行实时流应用程序使用自己的用户级传输协议在UDP上运行,以获得良好的应用程序性能,但在今天的大多数情况下,它们无法适应或正确响应网络拥塞。通过实现稳定的控制算法并公开自适应API,CM使应用程序能够轻松适应拥塞。应用程序根据当前的网络条件调整传输的数据。

The CM framework builds on recent work on TCP control block sharing [Touch97], integrated TCP congestion control (TCP-Int) [Balakrishnan98] and TCP sessions [Padmanabhan98]. [Touch97] advocates the sharing of some of the state in the TCP control block to improve transient transport performance and describes sharing across an ensemble of TCP connections. [Balakrishnan98],

CM框架建立在TCP控制块共享[Touch97]、集成TCP拥塞控制(TCP Int)[Balakrishnan98]和TCP会话[Padmanabhan98]的最新工作基础上。[Touch97]提倡共享TCP控制块中的某些状态,以提高瞬态传输性能,并描述了跨TCP连接集合的共享。[Balakrishnan98],

[Padmanabhan98], and [Eggert00] describe several experiments that quantify the benefits of sharing congestion state, including improved stability in the face of congestion and better loss recovery. Integrating loss recovery across concurrent connections significantly improves performance because losses on one connection can be detected by noticing that later data sent on another connection has been received and acknowledged. The CM framework extends these ideas in two significant ways: (i) it extends congestion management to non-TCP streams, which are becoming increasingly common and often do not implement proper congestion management, and (ii) it provides an API for applications to adapt their transmissions to current network conditions. For an extended discussion of the motivation for the CM, its architecture, API, and algorithms, see [Balakrishnan99]; for a description of an implementation and performance results, see [Andersen00].

[Padmanabhan98]和[Eggert00]描述了几个实验,这些实验量化了共享拥塞状态的好处,包括在拥塞面前提高稳定性和更好的损失恢复。跨并发连接集成丢失恢复可显著提高性能,因为可以通过注意到在另一个连接上发送的后续数据已被接收和确认来检测一个连接上的丢失。CM框架以两种重要的方式扩展了这些思想:(i)它将拥塞管理扩展到非TCP流,非TCP流正变得越来越普遍,并且通常无法实现适当的拥塞管理;(ii)它为应用程序提供了一个API,以使其传输适应当前的网络条件。有关CM动机、架构、API和算法的详细讨论,请参见[Balakrishnan99];有关实现和性能结果的描述,请参阅[Andersen00]。

The resulting end-host protocol architecture at the sender is shown in Figure 1. The CM helps achieve network stability by implementing stable congestion avoidance and control algorithms that are "TCP-friendly" [Mahdavi98] based on algorithms described in [Allman99]. However, it does not attempt to enforce proper congestion behavior for all applications (but it does not preclude a policer on the host that performs this task). Note that while the policer at the end-host can use CM, the network has to be protected against compromises to the CM and the policer at the end hosts, a task that requires router machinery [Floyd99a]. We do not address this issue further in this document.

发送方的最终主机协议架构如图1所示。CM通过基于[Allman99]中所述的算法,实现稳定的拥塞避免和控制算法[Mahdavi98],从而帮助实现网络稳定性。但是,它不会尝试对所有应用程序强制执行适当的拥塞行为(但它不会排除主机上执行此任务的policer)。请注意,虽然终端主机上的policer可以使用CM,但必须保护网络不受对终端主机上的CM和policer的损害,这是一项需要路由器机器的任务[Floyd99a]。我们在本文件中不再进一步讨论这个问题。

   |--------| |--------| |--------| |--------|       |--------------|
   |  HTTP  | |  FTP   | |  RTP 1 | |  RTP 2 |       |              |
   |--------| |--------| |--------| |--------|       |              |
       |          |         |  ^       |  ^          |              |
       |          |         |  |       |  |          |   Scheduler  |
       |          |         |  |       |  |  |---|   |              |
       |          |         |  |-------|--+->|   |   |              |
       |          |         |          |     |   |<--|              |
       v          v         v          v     |   |   |--------------|
   |--------| |--------|  |-------------|    |   |           ^
   |  TCP 1 | |  TCP 2 |  |    UDP 1    |    | A |           |
   |--------| |--------|  |-------------|    |   |           |
      ^   |      ^   |              |        |   |   |--------------|
      |   |      |   |              |        | P |-->|              |
      |   |      |   |              |        |   |   |              |
      |---|------+---|--------------|------->|   |   |  Congestion  |
          |          |              |        | I |   |              |
          v          v              v        |   |   |  Controller  |
     |-----------------------------------|   |   |   |              |
     |               IP                  |-->|   |   |              |
     |-----------------------------------|   |   |   |--------------|
                                             |---|
        
   |--------| |--------| |--------| |--------|       |--------------|
   |  HTTP  | |  FTP   | |  RTP 1 | |  RTP 2 |       |              |
   |--------| |--------| |--------| |--------|       |              |
       |          |         |  ^       |  ^          |              |
       |          |         |  |       |  |          |   Scheduler  |
       |          |         |  |       |  |  |---|   |              |
       |          |         |  |-------|--+->|   |   |              |
       |          |         |          |     |   |<--|              |
       v          v         v          v     |   |   |--------------|
   |--------| |--------|  |-------------|    |   |           ^
   |  TCP 1 | |  TCP 2 |  |    UDP 1    |    | A |           |
   |--------| |--------|  |-------------|    |   |           |
      ^   |      ^   |              |        |   |   |--------------|
      |   |      |   |              |        | P |-->|              |
      |   |      |   |              |        |   |   |              |
      |---|------+---|--------------|------->|   |   |  Congestion  |
          |          |              |        | I |   |              |
          v          v              v        |   |   |  Controller  |
     |-----------------------------------|   |   |   |              |
     |               IP                  |-->|   |   |              |
     |-----------------------------------|   |   |   |--------------|
                                             |---|
        

Figure 1

图1

The key components of the CM framework are (i) the API, (ii) the congestion controller, and (iii) the scheduler. The API is (in part) motivated by the requirements of application-level framing (ALF) [Clark90], and is described in Section 4. The CM internals (Section 5) include a congestion controller (Section 5.1) and a scheduler to orchestrate data transmissions between concurrent streams in a macroflow (Section 5.2). The congestion controller adjusts the aggregate transmission rate between sender and receiver based on its estimate of congestion in the network. It obtains feedback about its past transmissions from applications themselves via the API. The scheduler apportions available bandwidth amongst the different streams within each macroflow and notifies applications when they are permitted to send data. This document focuses on well-behaved applications; a future one will describe the sender-receiver protocol and header formats that will handle applications that do not incorporate their own feedback to the CM.

CM框架的关键组件是(i)API、(ii)拥塞控制器和(iii)调度器。API(部分)是由应用程序级框架(ALF)[Clark90]的要求驱动的,并在第4节中进行了描述。CM内部(第5节)包括拥塞控制器(第5.1节)和调度器,用于协调宏流中并发流之间的数据传输(第5.2节)。拥塞控制器根据其对网络中拥塞的估计来调整发送方和接收方之间的总传输速率。它通过API从应用程序本身获取有关其过去传输的反馈。调度器在每个宏流中的不同流之间分配可用带宽,并在允许应用程序发送数据时通知应用程序。本文档重点介绍性能良好的应用程序;未来的一个将描述发送方-接收方协议和报头格式,这些协议和报头格式将处理未将其自身反馈纳入CM的应用程序。

3. CM API
3. CM API

By convention, the IETF does not treat Application Programming Interfaces as standards track. However, it is considered important to have the CM API and CM algorithm requirements in one coherent document. The following section on the CM API uses the terms MUST,

按照惯例,IETF不将应用程序编程接口视为标准。然而,将CM API和CM算法要求放在一个连贯的文档中是很重要的。CM API的以下部分使用了术语“必须”,

SHOULD, etc., but the terms are meant to apply within the context of an implementation of the CM API. The section does not apply to congestion control implementations in general, only to those implementations offering the CM API.

应该等,但这些术语旨在应用于CM API实现的上下文中。本节一般不适用于拥塞控制实现,仅适用于提供CM API的实现。

Using the CM API, streams can determine their share of the available bandwidth, request and have their data transmissions scheduled, inform the CM about successful transmissions, and be informed when the CM's estimate of path bandwidth changes. Thus, the CM frees applications from having to maintain information about the state of congestion and available bandwidth along any path.

使用CM API,流可以确定其可用带宽的份额,请求并安排其数据传输,将成功传输告知CM,并且在CM的路径带宽估计改变时被告知。因此,CM使应用程序不必维护关于任何路径上的拥塞状态和可用带宽的信息。

The function prototypes below follow standard C language convention. We emphasize that these API functions are abstract calls and conformant CM implementations may differ in specific details, as long as equivalent functionality is provided.

下面的函数原型遵循标准C语言约定。我们强调,这些API函数是抽象调用,只要提供了等效的功能,一致的CM实现可能在具体细节上有所不同。

When a new stream is created by an application, it passes some information to the CM via the cm_open(stream_info) API call. Currently, stream_info consists of the following information: (i) the source IP address, (ii) the source port, (iii) the destination IP address, (iv) the destination port, and (v) the IP protocol number.

当应用程序创建一个新流时,它通过CM_open(stream_info)API调用将一些信息传递给CM。目前,stream_info由以下信息组成:(i)源IP地址,(ii)源端口,(iii)目标IP地址,(iv)目标端口,以及(v)IP协议号。

3.1 State maintenance
3.1 国家维护

1. Open: All applications MUST call cm_open(stream_info) before using the CM API. This returns a handle, cm_streamid, for the application to use for all further CM API invocations for that stream. If the returned cm_streamid is -1, then the cm_open() failed and that stream cannot use the CM.

1. 打开:在使用cm API之前,所有应用程序都必须调用cm_Open(stream_info)。这将返回一个句柄cm_streamid,供应用程序用于该流的所有后续cm-API调用。如果返回的cm_streamid为-1,则cm_open()失败,并且该流无法使用cm。

All other calls to the CM for a stream use the cm_streamid returned from the cm_open() call.

流对CM的所有其他调用都使用从CM_open()调用返回的CM_streamid。

2. Close: When a stream terminates, the application SHOULD invoke cm_close(cm_streamid) to inform the CM about the termination of the stream.

2. 关闭:当流终止时,应用程序应该调用cm_Close(cm_streamid)来通知cm流的终止。

3. Packet size: cm_mtu(cm_streamid) returns the estimated PMTU of the path between sender and receiver. Internally, this information SHOULD be obtained via path MTU discovery [Mogul90]. It MAY be statically configured in the absence of such a mechanism.

3. 数据包大小:cm_mtu(cm_streamid)返回发送方和接收方之间路径的估计PMTU。在内部,该信息应通过路径MTU发现[Mogul90]获得。它可以在没有这种机制的情况下进行静态配置。

3.2 Data transmission
3.2 数据传输

The CM accommodates two types of adaptive senders, enabling applications to dynamically adapt their content based on prevailing network conditions, and supporting ALF-based applications.

CM支持两种类型的自适应发送器,使应用程序能够根据当前的网络条件动态调整其内容,并支持基于ALF的应用程序。

1. Callback-based transmission. The callback-based transmission API puts the stream in firm control of deciding what to transmit at each point in time. To achieve this, the CM does not buffer any data; instead, it allows streams the opportunity to adapt to unexpected network changes at the last possible instant. Thus, this enables streams to "pull out" and repacketize data upon learning about any rate change, which is hard to do once the data has been buffered. The CM must implement a cm_request(i32 cm_streamid) call for streams wishing to send data in this style. After some time, depending on the rate, the CM MUST invoke a callback using cmapp_send(), which is a grant for the stream to send up to PMTU bytes. The callback-style API is the recommended choice for ALF-based streams. Note that cm_request() does not take the number of bytes or MTU-sized units as an argument; each call to cm_request() is an implicit request for sending up to PMTU bytes. The CM MAY provide an alternate interface, cm_request(int k). The cmapp_send callback for this request is granted the right to send up to k PMTU sized segments. Section 4.3 discusses the time duration for which the transmission grant is valid, while Section 5.2 describes how these requests are scheduled and callbacks made.

1. 基于回调的传输。基于回调的传输API将流置于确定在每个时间点传输什么的严格控制之下。为了实现这一点,CM不缓冲任何数据;相反,它使流有机会在最后一个可能的瞬间适应意外的网络变化。因此,这使得流能够在了解到任何速率变化时“拉出”并重新打包数据,这在数据缓冲后很难做到。CM必须对希望以这种方式发送数据的流执行CM_请求(i32 CM_streamid)调用。一段时间后,根据速率,CM必须使用cmapp_send()调用回调,这是流最多发送PMTU字节的授权。对于基于ALF的流,建议选择回调样式API。请注意,cm_request()不将字节数或MTU大小的单位作为参数;对cm_request()的每次调用都是一个隐式请求,最多可发送PMTU字节。CM可提供一个备用接口,即CM_请求(int k)。此请求的cmapp_发送回调被授予发送多达k个PMTU大小段的权限。第4.3节讨论了传输授权有效的持续时间,而第5.2节描述了如何安排这些请求和进行回调。

2. Synchronous-style. The above callback-based API accommodates a class of ALF streams that are "asynchronous." Asynchronous transmitters do not transmit based on a periodic clock, but do so triggered by asynchronous events like file reads or captured frames. On the other hand, there are many streams that are "synchronous" transmitters, which transmit periodically based on their own internal timers (e.g., an audio senders that sends at a constant sampling rate). While CM callbacks could be configured to periodically interrupt such transmitters, the transmit loop of such applications is less affected if they retain their original timer-based loop. In addition, it complicates the CM API to have a stream express the periodicity and granularity of its callbacks. Thus, the CM MUST export an API that allows such streams to be informed of changes in rates using the cmapp_update(u64 newrate, u32 srtt, u32 rttdev) callback function, where newrate is the new rate in bits per second for this stream, srtt is the current smoothed round trip time estimate in microseconds, and rttdev is the smoothed linear deviation in the round-trip time estimate calculated using the same algorithm as in TCP [Paxson00]. The newrate value reports an instantaneous rate calculated, for example, by taking the ratio of cwnd and srtt, and dividing by the fraction of that ratio allocated to the stream.

2. 同步风格。上述基于回调的API包含一类“异步”ALF流。异步发送器不基于周期时钟进行传输,而是由文件读取或捕获帧等异步事件触发。另一方面,有许多流是“同步”发射机,它们根据自己的内部定时器(例如,以恒定采样率发送的音频发射机)定期发送。虽然CM回调可配置为周期性中断此类发射机,但如果此类应用程序保留其原始基于定时器的环路,则其传输环路受影响较小。此外,让一个流表示其回调的周期性和粒度会使CM API变得复杂。因此,CM必须导出一个API,该API允许使用cmapp_update(u64 newrate,u32 srtt,u32 rttdev)回调函数将速率的变化告知此类流,其中newrate是该流的新速率(以比特/秒为单位),srtt是以微秒为单位的当前平滑往返时间估计,rttdev是使用与TCP[Paxson00]中相同的算法计算的往返时间估计中的平滑线性偏差。newrate值报告一个瞬时速率,例如,通过取cwnd和srtt的比率,除以分配给流的比率的分数来计算。

In response, the stream MUST adapt its packet size or change its timer interval to conform to (i.e., not exceed) the allowed rate. Of course, it may choose not to use all of this rate. Note that the CM is not on the data path of the actual transmission.

作为响应,流必须调整其数据包大小或更改其计时器间隔以符合(即,不超过)允许的速率。当然,它可能会选择不使用所有这些费率。请注意,CM不在实际传输的数据路径上。

To avoid unnecessary cmapp_update() callbacks that the application will only ignore, the CM MUST provide a cm_thresh(float rate_downthresh, float rate_upthresh, float rtt_downthresh, float rtt_upthresh) function that a stream can use at any stage in its execution. In response, the CM SHOULD invoke the callback only when the rate decreases to less than (rate_downthresh * lastrate) or increases to more than (rate_upthresh * lastrate), where lastrate is the rate last notified to the stream, or when the round-trip time changes correspondingly by the requisite thresholds. This information is used as a hint by the CM, in the sense the cmapp_update() can be called even if these conditions are not met.

为了避免应用程序只会忽略不必要的cmapp_update()回调,CM必须提供一个CM_thresh(float rate_downstresh、float rate_upthresh、float rtt_downstresh、float rtt_upthresh)函数,流可以在其执行的任何阶段使用该函数。作为响应,CM应仅在速率降低到小于(rate_downthresh*lastrate)或增加到大于(rate_upthresh*lastrate)时调用回调,其中lastrate是最后通知流的速率,或者当往返时间相应地改变所需阈值时调用回调。CM将此信息用作提示,从某种意义上说,即使不满足这些条件,也可以调用cmapp_update()。

The CM MUST implement a cm_query(i32 cm_streamid, u64* rate, u32* srtt, u32* rttdev) to allow an application to query the current CM state. This sets the rate variable to the current rate estimate in bits per second, the srtt variable to the current smoothed round-trip time estimate in microseconds, and rttdev to the mean linear deviation. If the CM does not have valid estimates for the macroflow, it fills in negative values for the rate, srtt, and rttdev.

CM必须实现CM_查询(i32 CM_streamid、u64*速率、u32*srtt、u32*rttdev),以允许应用程序查询当前CM状态。这将速率变量设置为当前速率估计值(以位/秒为单位),srtt变量设置为当前平滑往返时间估计值(以微秒为单位),rttdev设置为平均线性偏差。如果CM没有有效的宏流估计值,它将填充速率、srtt和rttdev的负值。

Note that a stream can use more than one of the above transmission APIs at the same time. In particular, the knowledge of sustainable rate is useful for asynchronous streams as well as synchronous ones; e.g., an asynchronous Web server disseminating images using TCP may use cmapp_send() to schedule its transmissions and cmapp_update() to decide whether to send a low-resolution or high-resolution image. A TCP implementation using the CM is described in Section 6.1.1, where the benefit of the cm_request() callback API for TCP will become apparent.

请注意,流可以同时使用上述多个传输API。特别是,可持续速率的知识对于异步流和同步流都很有用;e、 例如,使用TCP传播图像的异步Web服务器可以使用cmapp_send()来调度其传输,使用cmapp_update()来决定是发送低分辨率图像还是高分辨率图像。第6.1.1节中描述了使用CM的TCP实现,其中针对TCP的CM_request()回调API的好处将变得显而易见。

The reader will notice that the basic CM API does not provide an interface for buffered congestion-controlled transmissions. This is intentional, since this transmission mode can be implemented using the callback-based primitive. Section 6.1.2 describes how congestion-controlled UDP sockets may be implemented using the CM API.

读者将注意到,基本cmapi没有为缓冲拥塞控制传输提供接口。这是有意的,因为这种传输模式可以使用基于回调的原语实现。第6.1.2节描述了如何使用CM API实现拥塞控制UDP套接字。

3.3 Application notification
3.3 申请通知

When a stream receives feedback from receivers, it MUST use cm_update(i32 cm_streamid, u32 nrecd, u32 nlost, u8 lossmode, i32 rtt) to inform the CM about events such as congestion losses,

当流接收到来自接收器的反馈时,它必须使用cm_更新(i32 cm_streamid、u32 nrecd、u32 nlost、u8 lossmode、i32 rtt)将拥塞丢失等事件通知cm,

successful receptions, type of loss (timeout event, Explicit Congestion Notification [Ramakrishnan99], etc.) and round-trip time samples. The nrecd parameter indicates how many bytes were successfully received by the receiver since the last cm_update call, while the nrecd parameter identifies how many bytes were received were lost during the same time period. The rtt value indicates the round-trip time measured during the transmission of these bytes. The rtt value must be set to -1 if no valid round-trip sample was obtained by the application. The lossmode parameter provides an indicator of how a loss was detected. A value of CM_NO_FEEDBACK indicates that the application has received no feedback for all its outstanding data, and is reporting this to the CM. For example, a TCP that has experienced a timeout would use this parameter to inform the CM of this. A value of CM_LOSS_FEEDBACK indicates that the application has experienced some loss, which it believes to be due to congestion, but not all outstanding data has been lost. For example, a TCP segment loss detected using duplicate (selective) acknowledgments or other data-driven techniques fits this category. A value of CM_EXPLICIT_CONGESTION indicates that the receiver echoed an explicit congestion notification message. Finally, a value of CM_NO_CONGESTION indicates that no congestion-related loss has occurred. The lossmode parameter MUST be reported as a bit-vector where the bits correspond to CM_NO_FEEDBACK, CM_LOSS_FEEDBACK, CM_EXPLICIT_CONGESTION, and CM_NO_CONGESTION. Note that over links (paths) that experience losses for reasons other than congestion, an application SHOULD inform the CM of losses, with the CM_NO_CONGESTION field set.

成功接收、丢失类型(超时事件、显式拥塞通知[Ramakrishnan99]等)和往返时间样本。nrecd参数表示自上次cm_更新调用以来接收器成功接收的字节数,而nrecd参数表示在同一时间段内接收到的字节数和丢失的字节数。rtt值表示在传输这些字节期间测量的往返时间。如果应用程序未获得有效的往返样本,则rtt值必须设置为-1。lossmode参数提供了如何检测丢失的指示器。CM_NO_FEEDBACK的值表示应用程序未收到其所有未完成数据的任何反馈,并将此报告给CM。例如,遇到超时的TCP将使用此参数通知CM此情况。CM_LOSS_FEEDBACK的值表示应用程序经历了一些丢失,它认为这是由于拥塞造成的,但并非所有未完成的数据都丢失了。例如,使用重复(选择性)确认或其他数据驱动技术检测到的TCP段丢失属于此类。CM_EXPLICIT_拥塞值表示接收器回显拥塞通知消息。最后,CM_NO_拥塞值表示没有发生与拥塞相关的丢失。lossmode参数必须报告为位向量,其中位对应于CM_NO_反馈、CM_LOSS_反馈、CM_EXPLICIT_拥塞和CM_NO_拥塞。请注意,对于因拥塞以外的原因而丢失的链路(路径),应用程序应将丢失通知CM,并设置CM_NO_拥塞字段。

cm_notify(i32 cm_streamid, u32 nsent) MUST be called when data is transmitted from the host (e.g., in the IP output routine) to inform the CM that nsent bytes were just transmitted on a given stream. This allows the CM to update its estimate of the number of outstanding bytes for the macroflow and for the stream.

当从主机(例如,在IP输出例程中)传输数据时,必须调用cm_notify(i32 cm_streamid,u32 nsent),以通知cm nsent字节刚刚在给定流上传输。这允许CM更新其对宏流和流的未完成字节数的估计。

A cmapp_send() grant from the CM to an application is valid only for an expiration time, equal to the larger of the round-trip time and an implementation-dependent threshold communicated as an argument to the cmapp_send() callback function. The application MUST NOT send data based on this callback after this time has expired. Furthermore, if the application decides not to send data after receiving this callback, it SHOULD call cm_notify(stream_info, 0) to allow the CM to permit other streams in the macroflow to transmit data. The CM congestion controller MUST be robust to applications forgetting to invoke cm_notify(stream_info, 0) correctly, or applications that crash or disappear after having made a cm_request() call.

从CM到应用程序的cmapp_send()授权仅在过期时间内有效,过期时间等于往返时间和作为参数传递给cmapp_send()回调函数的实现相关阈值中的较大者。在此时间过期后,应用程序不得基于此回调发送数据。此外,如果应用程序在接收到此回调后决定不发送数据,则应调用cm_notify(stream_info,0),以允许cm允许宏流中的其他流发送数据。CM拥塞控制器必须对忘记正确调用CM_notify(stream_info,0)的应用程序,或在发出CM_request()调用后崩溃或消失的应用程序具有鲁棒性。

3.4 Querying
3.4 质疑

If applications wish to learn about per-stream available bandwidth and round-trip time, they can use the CM's cm_query(i32 cm_streamid, i64* rate, i32* srtt, i32* rttdev) call, which fills in the desired quantities. If the CM does not have valid estimates for the macroflow, it fills in negative values for the rate, srtt, and rttdev.

如果应用程序希望了解每个流的可用带宽和往返时间,它们可以使用CM的CM_查询(i32 CM_streamid、i64*速率、i32*srtt、i32*rttdev)调用,该调用将填充所需的数量。如果CM没有有效的宏流估计值,它将填充速率、srtt和rttdev的负值。

3.5 Sharing granularity
3.5 共享粒度

One of the decisions the CM needs to make is the granularity at which a macroflow is constructed, by deciding which streams belong to the same macroflow and share congestion information. The API provides two functions that allow applications to decide which of their streams ought to belong to the same macroflow.

CM需要做出的决定之一是通过决定哪些流属于相同的宏流并共享拥塞信息来构造宏流的粒度。API提供了两个函数,允许应用程序决定哪些流应该属于同一个宏流。

cm_getmacroflow(i32 cm_streamid) returns a unique i32 macroflow identifier. cm_setmacroflow(i32 cm_macroflowid, i32 cm_streamid) sets the macroflow of the stream cm_streamid to cm_macroflowid. If the cm_macroflowid that is passed to cm_setmacroflow() is -1, then a new macroflow is constructed and this is returned to the caller. Each call to cm_setmacroflow() overrides the previous macroflow association for the stream, should one exist.

cm_getmacroflow(i32 cm_streamid)返回唯一的i32宏流标识符。cm_setmacroflow(i32 cm_macroflowid,i32 cm_streamid)将流cm_streamid的宏流设置为cm_macroflowid。如果传递给cm_setmacroflow()的cm_macroflowid为-1,则会构造一个新的macroflow,并将其返回给调用者。对cm_setmacroflow()的每次调用都会覆盖流的上一个宏流关联(如果存在)。

The default suggested aggregation method is to aggregate by destination IP address; i.e., all streams to the same destination address are aggregated to a single macroflow by default. The cm_getmacroflow() and cm_setmacroflow() calls can then be used to change this as needed. We do note that there are some cases where this may not be optimal, even over best-effort networks. For example, when a group of receivers are behind a NAT device, the sender will see them all as one address. If the hosts behind the NAT are in fact connected over different bottleneck links, some of those hosts could see worse performance than before. It is possible to detect such hosts when using delay and loss estimates, although the specific mechanisms for doing so are beyond the scope of this document.

默认建议的聚合方法是按目标IP地址聚合;i、 例如,默认情况下,到同一目标地址的所有流聚合到单个宏流。然后,可以根据需要使用cm_getmacroflow()和cm_setmacroflow()调用来更改此设置。我们确实注意到,在某些情况下,这可能不是最优的,即使是在尽力而为的网络上。例如,当一组接收器位于NAT设备后面时,发送方将把它们都视为一个地址。如果NAT后面的主机实际上是通过不同的瓶颈链路连接的,那么其中一些主机的性能可能会比以前差。在使用延迟和损失估计时,可以检测到此类主机,尽管这样做的具体机制超出了本文档的范围。

The objective of this interface is to set up sharing of groups not sharing policy of relative weights of streams in a macroflow. The latter requires the scheduler to provide an interface to set sharing policy. However, because we want to support many different schedulers (each of which may need different information to set policy), we do not specify a complete API to the scheduler (but see

此接口的目标是建立组共享,而不是共享宏流中流的相对权重策略。后者要求调度器提供一个接口来设置共享策略。但是,由于我们希望支持许多不同的调度器(每个调度器可能需要不同的信息来设置策略),因此我们没有为调度器指定完整的API(但请参阅)

Section 5.2). A later guideline document is expected to describe a few simple schedulers (e.g., weighted round-robin, hierarchical scheduling) and the API they export to provide relative prioritization.

第5.2节)。稍后的指南文档将描述一些简单的调度程序(例如,加权循环调度、分层调度)以及它们导出以提供相对优先级的API。

4. CM internals
4. CM内部构件

This section describes the internal components of the CM. It includes a Congestion Controller and a Scheduler, with well-defined, abstract interfaces exported by them.

本节介绍CM的内部组件。它包括一个拥塞控制器和一个调度程序,以及由它们导出的定义良好的抽象接口。

4.1 Congestion controller
4.1 拥塞控制器

Associated with each macroflow is a congestion control algorithm; the collection of all these algorithms comprises the congestion controller of the CM. The control algorithm decides when and how much data can be transmitted by a macroflow. It uses application notifications (Section 4.3) from concurrent streams on the same macroflow to build up information about the congestion state of the network path used by the macroflow.

与每个宏流相关联的是拥塞控制算法;所有这些算法的集合包括CM的拥塞控制器。控制算法决定宏流何时以及传输多少数据。它使用来自同一宏流上并发流的应用程序通知(第4.3节)来建立有关宏流使用的网络路径的拥塞状态的信息。

The congestion controller MUST implement a "TCP-friendly" [Mahdavi98] congestion control algorithm. Several macroflows MAY (and indeed, often will) use the same congestion control algorithm but each macroflow maintains state about the network used by its streams.

拥塞控制器必须实现“TCP友好”[Mahdavi98]拥塞控制算法。多个宏流可能(事实上,通常会)使用相同的拥塞控制算法,但每个宏流保持其流所使用网络的状态。

The congestion control module MUST implement the following abstract interfaces. We emphasize that these are not directly visible to applications; they are within the context of a macroflow, and are different from the CM API functions of Section 4.

拥塞控制模块必须实现以下抽象接口。我们强调,这些应用程序不能直接看到;它们在宏流的上下文中,不同于第4节的CM API函数。

- void query(u64 *rate, u32 *srtt, u32 *rttdev): This function returns the estimated rate (in bits per second) and smoothed round trip time (in microseconds) for the macroflow.

- 无效查询(u64*速率、u32*srtt、u32*rttdev):此函数返回宏流的估计速率(以位/秒为单位)和平滑往返时间(以微秒为单位)。

- void notify(u32 nsent): This function MUST be used to notify the congestion control module whenever data is sent by an application. The nsent parameter indicates the number of bytes just sent by the application.

- void notify(u32 nsent):此功能必须用于在应用程序发送数据时通知拥塞控制模块。nsent参数表示应用程序刚刚发送的字节数。

- void update(u32 nsent, u32 nrecd, u32 rtt, u32 lossmode): This function is called whenever any of the CM streams associated with a macroflow identifies that data has reached the receiver or has been lost en route. The nrecd parameter indicates the number of bytes that have just arrived at the receiver. The nsent parameter is the sum of the number of bytes just received and the

- 无效更新(u32 nsent、u32 nrecd、u32 rtt、u32 lossmode):每当与宏流相关联的任何CM流确定数据已到达接收器或在路由中丢失时,调用此函数。nrecd参数表示刚刚到达接收器的字节数。nsent参数是刚刚接收的字节数和

number of bytes identified as lost en route. The rtt parameter is the estimated round trip time in microseconds during the transfer. The lossmode parameter provides an indicator of how a loss was detected (section 4.3).

在路由中标识为丢失的字节数。rtt参数是传输过程中以微秒为单位的估计往返时间。lossmode参数提供了如何检测损失的指标(第4.3节)。

Although these interfaces are not visible to applications, the congestion controller MUST implement these abstract interfaces to provide for modular inter-operability with different separately-developed schedulers.

虽然这些接口对应用程序不可见,但拥塞控制器必须实现这些抽象接口,以提供与不同单独开发的调度器的模块化互操作性。

The congestion control module MUST also call the associated scheduler's schedule function (section 5.2) when it believes that the current congestion state allows an MTU-sized packet to be sent.

当拥塞控制模块认为当前拥塞状态允许发送MTU大小的数据包时,它还必须调用相关调度器的调度功能(第5.2节)。

4.2 Scheduler
4.2 调度程序

While it is the responsibility of the congestion control module to determine when and how much data can be transmitted, it is the responsibility of a macroflow's scheduler module to determine which of the streams should get the opportunity to transmit data.

虽然拥塞控制模块负责确定何时以及可以传输多少数据,但宏流的调度器模块负责确定哪些流应该有机会传输数据。

The Scheduler MUST implement the following interfaces:

计划程序必须实现以下接口:

- void schedule(u32 num_bytes): When the congestion control module determines that data can be sent, the schedule() routine MUST be called with no more than the number of bytes that can be sent. In turn, the scheduler MAY call the cmapp_send() function that CM applications must provide.

- void schedule(u32 num_bytes):当拥塞控制模块确定可以发送数据时,调用schedule()例程时,不能超过可以发送的字节数。反过来,调度器可以调用CM应用程序必须提供的cmapp_send()函数。

- float query_share(i32 cm_streamid): This call returns the described stream's share of the total bandwidth available to the macroflow. This call combined with the query call of the congestion controller provides the information to satisfy an application's cm_query() request.

- float query_share(i32 cm_streamid):此调用返回描述的流在宏流可用总带宽中的份额。此调用与拥塞控制器的查询调用相结合,提供满足应用程序cm_query()请求的信息。

- void notify(i32 cm_streamid, u32 nsent): This interface is used to notify the scheduler module whenever data is sent by a CM application. The nsent parameter indicates the number of bytes just sent by the application.

- void notify(i32 cm_streamid,u32 nsent):此接口用于在cm应用程序发送数据时通知调度程序模块。nsent参数表示应用程序刚刚发送的字节数。

The Scheduler MAY implement many additional interfaces. As experience with CM schedulers increases, future documents may make additions and/or changes to some parts of the scheduler API.

调度器可以实现许多附加接口。随着CM调度器经验的增加,未来的文档可能会对调度器API的某些部分进行添加和/或更改。

5. Examples
5. 例子
5.1 Example applications
5.1 示例应用程序
   This section describes three possible uses of the CM API by
   applications.  We describe two asynchronous applications---an
   implementation of a TCP sender and an implementation of congestion-
   controlled UDP sockets, and a synchronous application---a streaming
   audio server.  More details of these applications and CM
   implementation optimizations for efficient operation are described in
   [Andersen00].
        
   This section describes three possible uses of the CM API by
   applications.  We describe two asynchronous applications---an
   implementation of a TCP sender and an implementation of congestion-
   controlled UDP sockets, and a synchronous application---a streaming
   audio server.  More details of these applications and CM
   implementation optimizations for efficient operation are described in
   [Andersen00].
        

All applications that use the CM MUST incorporate feedback from the receiver. For example, it must periodically (typically once or twice per round trip time) determine how many of its packets arrived at the receiver. When the source gets this feedback, it MUST use cm_update() to inform the CM of this new information. This results in the CM updating ownd and may result in the CM changing its estimates and calling cmapp_update() of the streams of the macroflow.

所有使用CM的应用程序必须包含来自接收器的反馈。例如,它必须定期(通常每个往返时间一次或两次)确定有多少数据包到达接收器。当源收到此反馈时,它必须使用cm_update()将此新信息通知给cm。这导致CM更新ownd,并且可能导致CM改变其估计并调用宏流流的cmapp_update()。

The protocols in this section are examples and suggestions for implementation, rather than requirements for any conformant implementation.

本节中的协议是实施的示例和建议,而不是任何一致性实施的要求。

5.1.1 TCP
5.1.1 传输控制协议

A TCP implementation that uses CM should use the cmapp_send() callback API. TCP only identifies which data it should send upon the arrival of an acknowledgement or expiration of a timer. As a result, it requires tight control over when and if new data or retransmissions are sent.

使用CM的TCP实现应该使用cmapp_send()回调API。TCP仅识别在确认到达或计时器过期时应发送的数据。因此,它需要严格控制何时以及是否发送新数据或重新传输。

When TCP either connects to or accepts a connection from another host, it performs a cm_open() call to associate the TCP connection with a cm_streamid.

当TCP连接到另一台主机或接受来自另一台主机的连接时,它将执行cm_open()调用,以将TCP连接与cm_streamid关联。

Once a connection is established, the CM is used to control the transmission of outgoing data. The CM eliminates the need for tracking and reacting to congestion in TCP, because the CM and its transmission API ensure proper congestion behavior. Loss recovery is still performed by TCP based on fast retransmissions and recovery as well as timeouts. In addition, TCP is also modified to have its own outstanding window (tcp_ownd) estimate. Whenever data segments are sent from its cmapp_send() callback, TCP updates its tcp_ownd value. The ownd variable is also updated after each cm_update() call. TCP also maintains a count of the number of outstanding segments (pkt_cnt). At any time, TCP can calculate the average packet size (avg_pkt_size) as tcp_ownd/pkt_cnt. The avg_pkt_size is used by TCP

一旦建立连接,CM用于控制传出数据的传输。CM消除了对TCP中拥塞的跟踪和响应需求,因为CM及其传输API确保了正确的拥塞行为。丢失恢复仍然由TCP基于快速重传和恢复以及超时来执行。此外,TCP还被修改为具有自己的未完成窗口(TCP_ownd)估计。无论何时从其cmapp_send()回调发送数据段,TCP都会更新其TCP_ownd值。ownd变量也会在每次cm_update()调用后更新。TCP还维护未完成段数(pkt_cnt)的计数。在任何时候,TCP都可以将平均数据包大小(avg_pkt_size)计算为TCP_ownd/pkt_cnt。TCP使用平均pkt_大小

to help estimate the amount of outstanding data. Note that this is not needed if the SACK option is used on the connection, since this information is explicitly available.

帮助估计未完成数据的数量。请注意,如果在连接上使用SACK选项,则不需要此选项,因为此信息是显式可用的。

The TCP output routines are modified as follows:

TCP输出例程修改如下:

1. All congestion window (cwnd) checks are removed.

1. 将删除所有拥塞窗口(cwnd)检查。

2. When application data is available. The TCP output routines perform all non-congestion checks (Nagle algorithm, receiver-advertised window check, etc). If these checks pass, the output routine queues the data and calls cm_request() for the stream.

2. 当应用程序数据可用时。TCP输出例程执行所有非拥塞检查(Nagle算法、接收器广告窗口检查等)。如果这些检查通过,输出例程将数据排队,并为流调用cm_request()。

3. If incoming data or timers result in a loss being detected, the retransmission is also placed in a queue and cm_request() is called for the stream.

3. 如果传入的数据或计时器导致检测到丢失,则重传也会放入队列中,并为流调用cm_request()。

4. The cmapp_send() callback for TCP is set to an output routine. If any retransmission is enqueued, the routine outputs the retransmission. Otherwise, the routine outputs as much new data as the TCP connection state allows. However, the cmapp_send() never sends more than a single segment per call. This routine arranges for the other output computations to be done, such as header and options computations.

4. TCP的cmapp_send()回调设置为输出例程。如果任何重传排队,例程将输出重传。否则,例程将输出TCP连接状态允许的尽可能多的新数据。但是,cmapp_send()每次调用发送的数据段不会超过一个。此例程安排要完成的其他输出计算,例如标题和选项计算。

The IP output routine on the host calls cm_notify() when the packets are actually sent out. Because it does not know which cm_streamid is responsible for the packet, cm_notify() takes the stream_info as argument (see Section 4 for what the stream_info should contain). Because cm_notify() reports the IP payload size, TCP keeps track of the total header size and incorporates these updates.

当数据包实际发出时,主机上的IP输出例程调用cm_notify()。因为它不知道哪个cm_streamid负责该数据包,所以cm_notify()将stream_info作为参数(关于stream_info应该包含的内容,请参见第4节)。由于cm_notify()报告IP有效负载大小,TCP跟踪总头大小并合并这些更新。

The TCP input routines are modified as follows:

TCP输入例程修改如下:

1. RTT estimation is done as normal using either timestamps or Karn's algorithm. Any rtt estimate that is generated is passed to CM via the cm_update call.

1. RTT估计通常使用时间戳或Karn算法进行。生成的任何rtt估计值都通过CM_更新调用传递给CM。

2. All cwnd and slow start threshold (ssthresh) updates are removed.

2. 删除所有cwnd和慢速启动阈值(ssthresh)更新。

3. Upon the arrival of an ack for new data, TCP computes the value of in_flight (the amount of data in flight) as snd_max-ack-1 (i.e., MAX Sequence Sent - Current Ack - 1). TCP then calls cm_update(streamid, tcp_ownd - in_flight, 0, CM_NO_CONGESTION, rtt).

3. 当新数据的ack到达时,TCP将飞行中的值(飞行中的数据量)计算为snd_max-ack-1(即发送的最大序列-当前ack-1)。TCP然后调用cm_更新(streamid、TCP_ownd-in_flight、0、cm_NO_拥塞、rtt)。

4. Upon the arrival of a duplicate acknowledgement, TCP must check its dupack count (dup_acks) to determine its action. If dup_acks < 3, the TCP does nothing. If dup_acks == 3, TCP assumes that a packet was lost and that at least 3 packets arrived to generate these duplicate acks. Therefore, it calls cm_update(streamid, 4 * avg_pkt_size, 3 * avg_pkt_size, CM_LOSS_FEEDBACK, rtt). The average packet size is used since the acknowledgments do not indicate exactly how much data has reached the other end. Most TCP implementations interpret a duplicate ACK as an indication that a full MSS has reached its destination. Once a new ACK is received, these TCP sender implementations may resynchronize with TCP receiver. The CM API does not provide a mechanism for TCP to pass information from this resynchronization. Therefore, TCP can only infer the arrival of an avg_pkt_size amount of data from each duplicate ack. TCP also enqueues a retransmission of the lost segment and calls cm_request(). If dup_acks > 3, TCP assumes that a packet has reached the other end and caused this ack to be sent. As a result, it calls cm_update(streamid, avg_pkt_size, avg_pkt_size, CM_NO_CONGESTION, rtt).

4. 在收到重复确认后,TCP必须检查其重复确认计数(dup_acks)以确定其操作。如果dup_acks<3,则TCP不执行任何操作。如果dup_acks==3,TCP假定一个数据包丢失,并且至少有3个数据包到达以生成这些重复的ack。因此,它调用cm_更新(streamid,4*avg_pkt_size,3*avg_pkt_size,cm_LOSS_FEEDBACK,rtt)。使用平均数据包大小,因为确认并不确切指示有多少数据到达了另一端。大多数TCP实现将重复ACK解释为完整MSS已到达其目的地的指示。一旦收到新的ACK,这些TCP发送方实现可能会与TCP接收方重新同步。CM API不提供TCP通过此重新同步传递信息的机制。因此,TCP只能从每个重复的ack中推断出平均大小的数据量。TCP还使丢失段的重新传输排队,并调用cm_request()。如果dup_acks>3,TCP假定数据包已到达另一端并导致发送此ack。因此,它调用cm_更新(streamid、avg_pkt_大小、avg_pkt_大小、cm_无拥塞、rtt)。

5. Upon the arrival of a partial acknowledgment (one that does not exceed the highest segment transmitted at the time the loss occurred, as defined in [Floyd99b]), TCP assumes that a packet was lost and that the retransmitted packet has reached the recipient. Therefore, it calls cm_update(streamid, 2 * avg_pkt_size, avg_pkt_size, CM_NO_CONGESTION, rtt). CM_NO_CONGESTION is used since the loss period has already been reported. TCP also enqueues a retransmission of the lost segment and calls cm_request().

5. 当部分确认(如[Floyd99b]中所定义,不超过丢失时传输的最高段)到达时,TCP假定数据包丢失,且重新传输的数据包已到达接收方。因此,它调用cm_更新(streamid,2*avg_pkt_大小,avg_pkt_大小,cm_无拥塞,rtt)。由于已经报告了损失期,因此不使用CM_拥塞。TCP还使丢失段的重新传输排队,并调用cm_request()。

When the TCP retransmission timer expires, the sender identifies that a segment has been lost and calls cm_update(streamid, avg_pkt_size, 0, CM_NO_FEEDBACK, 0) to signify that no feedback has been received from the receiver and that one segment is sure to have "left the pipe." TCP also enqueues a retransmission of the lost segment and calls cm_request().

当TCP重传计时器过期时,发送方确定某个段已丢失,并调用cm_update(streamid,avg_pkt_size,0,cm_NO_FEEDBACK,0),以表示未收到来自接收方的反馈,并且一个段肯定已“离开管道”TCP还使丢失段的重新传输排队,并调用cm_request()。

5.1.2 Congestion-controlled UDP
5.1.2 拥塞控制UDP

Congestion-controlled UDP is a useful CM application, which we describe in the context of Berkeley sockets [Stevens94]. They provide the same functionality as standard Berkeley UDP sockets, but instead of immediately sending the data from the kernel packet queue to lower layers for transmission, the buffered socket implementation makes calls to the API exported by the CM inside the kernel and gets callbacks from the CM. When a CM UDP socket is created, it is bound to a particular stream. Later, when data is added to the packet queue, cm_request() is called on the stream associated with the

拥塞控制UDP是一个有用的CM应用程序,我们在Berkeley sockets[Stevens94]的上下文中描述了它。它们提供与标准Berkeley UDP套接字相同的功能,但缓冲套接字实现没有立即将数据从内核数据包队列发送到较低层进行传输,而是调用内核中CM导出的API,并从CM获取回调。创建CM UDP套接字时,它将绑定到特定流。稍后,当数据添加到数据包队列时,将在与数据包队列相关联的流上调用cm_request()

socket. When the CM schedules this stream for transmission, it calls udp_ccappsend() in the UDP module. This function transmits one MTU from the packet queue, and schedules the transmission of any remaining packets. The in-kernel implementation of the CM UDP API should not require any additional data copies and should support all standard UDP options. Modifying existing applications to use congestion-controlled UDP requires the implementation of a new socket option on the socket. To work correctly, the sender must obtain feedback about congestion. This can be done in at least two ways: (i) the UDP receiver application can provide feedback to the sender application, which will inform the CM of network conditions using cm_update(); (ii) the UDP receiver implementation can provide feedback to the sending UDP. Note that this latter alternative requires changes to the receiver's network stack and the sender UDP cannot assume that all receivers support this option without explicit negotiation.

插座当CM调度此流进行传输时,它会在udp模块中调用udp_ccappsend()。此函数用于从数据包队列传输一个MTU,并计划任何剩余数据包的传输。CM UDP API的内核内实现不需要任何额外的数据拷贝,并且应支持所有标准UDP选项。修改现有应用程序以使用拥塞控制UDP需要在套接字上实现新的套接字选项。要正确工作,发送方必须获得有关拥塞的反馈。这至少可以通过两种方式完成:(i)UDP接收方应用程序可以向发送方应用程序提供反馈,发送方应用程序将使用CM_update()通知CM网络状况;(ii)UDP接收器实现可向发送UDP提供反馈。请注意,后一种选择需要更改接收方的网络堆栈,并且发送方UDP不能假定所有接收方都支持此选项,而无需进行明确协商。

5.1.3 Audio server
5.1.3 音频服务器

A typical audio application often has access to the sample in a multitude of data rates and qualities. The objective of the application is then to deliver the highest possible quality of audio (typically the highest data rate) its clients. The selection of which version of audio to transmit should be based on the current congestion state of the network. In addition, the source will want audio delivered to its users at a consistent sampling rate. As a result, it must send data a regular rate, minimizing delaying transmissions and reducing buffering before playback. To meet these requirements, this application can use the synchronous sender API (Section 4.2).

典型的音频应用程序通常可以访问多种数据速率和质量的样本。然后,应用程序的目标是为其客户端提供尽可能高的音频质量(通常是最高的数据速率)。选择要传输的音频版本应基于网络的当前拥塞状态。此外,音频源希望以一致的采样率向用户提供音频。因此,它必须以固定的速率发送数据,最大限度地减少传输延迟,并减少回放前的缓冲。为了满足这些要求,此应用程序可以使用同步发送器API(第4.2节)。

When the source first starts, it uses the cm_query() call to get an initial estimate of network bandwidth and delay. If some other streams on that macroflow have already been active, then it gets an initial estimate that is valid; otherwise, it gets negative values, which it ignores. It then chooses an encoding that does not exceed these estimates (or, in the case of an invalid estimate, uses application-specific initial values) and begins transmitting data. The application also implements the cmapp_update() callback. When the CM determines that network characteristics have changed, it calls the application's cmapp_update() function and passes it a new rate and round-trip time estimate. The application must change its choice of audio encoding to ensure that it does not exceed these new estimates.

当源第一次启动时,它使用cm_query()调用获取网络带宽和延迟的初始估计值。如果该宏流上的一些其他流已经处于活动状态,那么它会得到一个有效的初始估计;否则,它会得到负值,而忽略该值。然后,它选择不超过这些估计值的编码(或者,在估计值无效的情况下,使用特定于应用程序的初始值),并开始传输数据。该应用程序还实现了cmapp_update()回调。当CM确定网络特征已更改时,它将调用应用程序的cmapp_update()函数,并向其传递新的速率和往返时间估计值。应用程序必须更改其音频编码的选择,以确保其不会超过这些新的估计值。

5.2 Example congestion control module
5.2 拥塞控制模块示例

To illustrate the responsibilities of a congestion control module, the following describes some of the actions of a simple TCP-like congestion control module that implements Additive Increase Multiplicative Decrease congestion control (AIMD_CC):

为了说明拥塞控制模块的职责,以下描述了实现加法-递增-乘法-递减拥塞控制(AIMD_-CC)的简单TCP类拥塞控制模块的一些操作:

- query(): AIMD_CC returns the current congestion window (cwnd) divided by the smoothed rtt (srtt) as its bandwidth estimate. It returns the smoothed rtt estimate as srtt.

- query():AIMD_CC返回当前拥塞窗口(cwnd)除以平滑rtt(srtt)作为其带宽估计。它将平滑的rtt估计值作为srtt返回。

- notify(): AIMD_CC adds the number of bytes sent to its outstanding data window (ownd).

- notify():AIMD_CC添加发送到其未完成数据窗口(ownd)的字节数。

- update(): AIMD_CC subtracts nsent from ownd. If the value of rtt is non-zero, AIMD_CC updates srtt using the TCP srtt calculation. If the update indicates that data has been lost, AIMD_CC sets cwnd to 1 MTU if the loss_mode is CM_NO_FEEDBACK and to cwnd/2 (with a minimum of 1 MTU) if the loss_mode is CM_LOSS_FEEDBACK or CM_EXPLICIT_CONGESTION. AIMD_CC also sets its internal ssthresh variable to cwnd/2. If no loss had occurred, AIMD_CC mimics TCP slow start and linear growth modes. It increments cwnd by nsent when cwnd < ssthresh (bounded by a maximum of ssthresh-cwnd) and by nsent * MTU/cwnd when cwnd > ssthresh.

- update():AIMD_CC从ownd中减去nsent。如果rtt的值不为零,AIMD_CC将使用TCP srtt计算更新srtt。如果更新表明数据已丢失,AIMD_CC将cwnd设置为1 MTU(如果丢失模式为CM_无反馈),将cwnd设置为1 MTU(如果丢失模式为CM_丢失反馈或CM_显式拥塞),将cwnd设置为cwnd/2(至少1 MTU)。AIMD_CC还将其内部ssthresh变量设置为cwnd/2。如果没有发生丢失,AIMD_CC将模拟TCP慢启动和线性增长模式。当cwnd<ssthresh(以ssthresh cwnd的最大值为界)时,它将cwnd增加nsent,当cwnd>ssthresh时,它将增加nsent*MTU/cwnd。

- When cwnd or ownd are updated and indicate that at least one MTU may be transmitted, AIMD_CC calls the CM to schedule a transmission.

- 当更新cwnd或ownd并指示至少可以传输一个MTU时,AIMD_CC呼叫CM以安排传输。

5.3 Example Scheduler Module
5.3 示例调度程序模块

To clarify the responsibilities of a scheduler module, the following describes some of the actions of a simple round robin scheduler module (RR_sched):

为了阐明调度程序模块的职责,以下描述了简单循环调度程序模块(RR_sched)的一些操作:

- schedule(): RR_sched schedules as many streams as possible in round robin fashion.

- schedule():RR_sched以循环方式调度尽可能多的流。

- query_share(): RR_sched returns 1/(number of streams in macroflow).

- query_share():RR_sched返回1/(宏流中的流数)。

- notify(): RR_sched does nothing. Round robin scheduling is not affected by the amount of data sent.

- notify():RR_sched不执行任何操作。循环调度不受发送的数据量的影响。

6. Security Considerations
6. 安全考虑

The CM provides many of the same services that the congestion control in TCP provides. As such, it is vulnerable to many of the same security problems. For example, incorrect reports of losses and

CM提供了许多与TCP中的拥塞控制相同的服务。因此,它容易受到许多同样的安全问题的影响。例如,错误的损失和损失报告

transmissions will give the CM an inaccurate picture of the network's congestion state. By giving CM a high estimate of congestion, an attacker can degrade the performance observed by applications. For example, a stream on a host can arbitrarily slow down any other stream on the same macroflow, a form of denial of service.

传输将向CM提供网络拥塞状态的不准确图像。通过向CM提供高拥塞估计值,攻击者可以降低应用程序观察到的性能。例如,主机上的流可以任意减慢同一宏流上的任何其他流,这是一种拒绝服务的形式。

The more dangerous form of attack occurs when an application gives the CM a low estimate of congestion. This would cause CM to be overly aggressive and allow data to be sent much more quickly than sound congestion control policies would allow.

当应用程序向CM提供较低的拥塞估计值时,会发生更危险的攻击形式。这将导致CM过于咄咄逼人,使得数据的发送速度比合理的拥塞控制政策所允许的要快得多。

[Touch97] describes a number of the security problems that arise with congestion information sharing. An additional vulnerability (not covered by [Touch97])) occurs because applications have access through the CM API to control shared state that will affect other applications on the same computer. For instance, a poorly designed, possibly a compromised, or intentionally malicious UDP application could misuse cm_update() to cause starvation and/or too-aggressive behavior of others in the macroflow.

[Touch97]描述了拥塞信息共享中出现的一些安全问题。由于应用程序可以通过CM API访问控制共享状态,从而影响同一台计算机上的其他应用程序,因此会出现另一个漏洞(不包括在[Touch97]中)。例如,一个设计不良、可能是被破坏的或故意恶意的UDP应用程序可能会滥用cm_update(),导致宏流中其他应用程序出现饥饿和/或过度攻击行为。

7. References
7. 工具书类

[Allman99] Allman, M. and Paxson, V., "TCP Congestion Control", RFC 2581, April 1999.

[Allman99]Allman,M.和Paxson,V.,“TCP拥塞控制”,RFC 25811999年4月。

[Andersen00] Balakrishnan, H., System Support for Bandwidth Management and Content Adaptation in Internet Applications, Proc. 4th Symp. on Operating Systems Design and Implementation, San Diego, CA, October 2000. Available from http://nms.lcs.mit.edu/papers/cm-osdi2000.html

[Andersen00]Balakrishnan,H.,互联网应用中带宽管理和内容自适应的系统支持,Proc。第四交响乐团。《操作系统设计与实施》,加利福尼亚州圣地亚哥,2000年10月。可从http://nms.lcs.mit.edu/papers/cm-osdi2000.html

[Balakrishnan98] Balakrishnan, H., Padmanabhan, V., Seshan, S., Stemm, M., and Katz, R., "TCP Behavior of a Busy Web Server: Analysis and Improvements," Proc. IEEE INFOCOM, San Francisco, CA, March 1998.

[Balakrishnan98]Balakrishnan,H.,Padmanabhan,V.,Seshan,S.,Stemp,M.,和Katz,R.,“繁忙Web服务器的TCP行为:分析和改进”,Proc。IEEE iFocom,旧金山,CA,1998年3月。

[Balakrishnan99] Balakrishnan, H., Rahul, H., and Seshan, S., "An Integrated Congestion Management Architecture for Internet Hosts," Proc. ACM SIGCOMM, Cambridge, MA, September 1999.

[Balakrishnan99]Balakrishnan,H.,Rahul,H.,和Seshan,S.,“互联网主机的集成拥塞管理架构”,Proc。ACM SIGCOMM,马萨诸塞州剑桥,1999年9月。

   [Bradner96]       Bradner, S., "The Internet Standards Process ---
                     Revision 3", BCP 9, RFC 2026, October 1996.
        
   [Bradner96]       Bradner, S., "The Internet Standards Process ---
                     Revision 3", BCP 9, RFC 2026, October 1996.
        

[Bradner97] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.

[Bradner97]Bradner,S.,“RFC中用于表示需求水平的关键词”,BCP 14,RFC 2119,1997年3月。

[Clark90] Clark, D. and Tennenhouse, D., "Architectural Consideration for a New Generation of Protocols", Proc. ACM SIGCOMM, Philadelphia, PA, September 1990.

[Clark90]Clark,D.和Tennenhouse,D.,“新一代协议的架构考虑”,Proc。ACM SIGCOMM,宾夕法尼亚州费城,1990年9月。

[Eggert00] Eggert, L., Heidemann, J., and Touch, J., "Effects of Ensemble TCP," ACM Computer Comm. Review, January 2000.

[Eggert00]Eggert,L.,Heidemann,J.,和Touch,J.,“集成TCP的影响”,ACM计算机通讯评论,2000年1月。

[Floyd99a] Floyd, S. and Fall, K.," Promoting the Use of End-to-End Congestion Control in the Internet," IEEE/ACM Trans. on Networking, 7(4), August 1999, pp. 458-472.

[Floyd99a]Floyd,S.和Fall,K.,“促进互联网中端到端拥塞控制的使用”,IEEE/ACM Trans。关于网络,7(4),1999年8月,第458-472页。

[Floyd99b] Floyd, S. and T. Henderson,"The New Reno Modification to TCP's Fast Recovery Algorithm," RFC 2582, April 1999.

[Floyd99b]Floyd,S.和T.Henderson,“TCP快速恢复算法的新雷诺修正案”,RFC 25821999年4月。

[Jacobson88] Jacobson, V., "Congestion Avoidance and Control," Proc. ACM SIGCOMM, Stanford, CA, August 1988.

[Jacobson88]Jacobson,V.,“拥塞避免和控制”,Proc。ACM SIGCOMM,加利福尼亚州斯坦福市,1988年8月。

   [Mahdavi98]       Mahdavi, J. and Floyd, S., "The TCP Friendly
                     Website,"
                     http://www.psc.edu/networking/tcp_friendly.html
        
   [Mahdavi98]       Mahdavi, J. and Floyd, S., "The TCP Friendly
                     Website,"
                     http://www.psc.edu/networking/tcp_friendly.html
        

[Mogul90] Mogul, J. and S. Deering, "Path MTU Discovery," RFC 1191, November 1990.

[Mogul90]Mogul,J.和S.Deering,“MTU发现路径”,RFC191990年11月。

[Padmanabhan98] Padmanabhan, V., "Addressing the Challenges of Web Data Transport," PhD thesis, Univ. of California, Berkeley, December 1998.

[Padmanabhan 98]Padmanabhan,V.,“应对网络数据传输的挑战”,加州大学伯克利分校博士论文,1998年12月。

[Paxson00] Paxson, V. and M. Allman, "Computing TCP's Retransmission Timer", RFC 2988, November 2000.

[Paxson 00]Paxson,V.和M.Allman,“计算TCP的重传计时器”,RFC 2988,2000年11月。

[Postel81] Postel, J., Editor, "Transmission Control Protocol", STD 7, RFC 793, September 1981.

[Postel81]Postel,J.,编辑,“传输控制协议”,STD 7,RFC 793,1981年9月。

[Ramakrishnan99] Ramakrishnan, K. and Floyd, S., "A Proposal to Add Explicit Congestion Notification (ECN) to IP," RFC 2481, January 1999.

[Ramakrishnan99]Ramakrishnan,K.和Floyd,S.,“向IP添加显式拥塞通知(ECN)的建议”,RFC 2481,1999年1月。

[Stevens94] Stevens, W., TCP/IP Illustrated, Volume 1. Addison-Wesley, Reading, MA, 1994.

[Stevens94]Stevens,W.,TCP/IP图解,第1卷。艾迪生·韦斯利,雷丁,马萨诸塞州,1994年。

[Touch97] Touch, J., "TCP Control Block Interdependence", RFC 2140, April 1997.

[Touch97]Touch,J.,“TCP控制块相互依赖”,RFC 2140,1997年4月。

8. Acknowledgments
8. 致谢

We thank David Andersen, Deepak Bansal, and Dorothy Curtis for their work on the CM design and implementation. We thank Vern Paxson for his detailed comments, feedback, and patience, and Sally Floyd, Mark Handley, and Steven McCanne for useful feedback on the CM architecture. Allison Mankin and Joe Touch provided several useful comments on previous drafts of this document.

我们感谢David Andersen、Deepak Bansal和Dorothy Curtis在CM设计和实现方面所做的工作。我们感谢Vern Paxson的详细评论、反馈和耐心,感谢Sally Floyd、Mark Handley和Steven McCanne对CM架构的有用反馈。Allison Mankin和Joe Touch就本文件的前几稿提供了一些有用的评论。

9. Authors' Addresses
9. 作者地址

Hari Balakrishnan Laboratory for Computer Science 200 Technology Square Massachusetts Institute of Technology Cambridge, MA 02139

哈里巴拉克里希南计算机科学实验室麻省理工学院科技广场200号马萨诸塞州剑桥02139

   EMail: hari@lcs.mit.edu
   Web: http://nms.lcs.mit.edu/~hari/
        
   EMail: hari@lcs.mit.edu
   Web: http://nms.lcs.mit.edu/~hari/
        

Srinivasan Seshan School of Computer Science Carnegie Mellon University 5000 Forbes Ave. Pittsburgh, PA 15213

斯里尼瓦桑·塞山计算机科学学院卡内基梅隆大学福布斯大道5000号,宾夕法尼亚州匹兹堡15213

   EMail: srini@cmu.edu
   Web: http://www.cs.cmu.edu/~srini/
        
   EMail: srini@cmu.edu
   Web: http://www.cs.cmu.edu/~srini/
        

Full Copyright Statement

完整版权声明

Copyright (C) The Internet Society (2001). All Rights Reserved.

版权所有(C)互联网协会(2001年)。版权所有。

This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Internet Society or other Internet organizations, except as needed for the purpose of developing Internet standards in which case the procedures for copyrights defined in the Internet Standards process must be followed, or as required to translate it into languages other than English.

本文件及其译本可复制并提供给他人,对其进行评论或解释或协助其实施的衍生作品可全部或部分编制、复制、出版和分发,不受任何限制,前提是上述版权声明和本段包含在所有此类副本和衍生作品中。但是,不得以任何方式修改本文件本身,例如删除版权通知或对互联网协会或其他互联网组织的引用,除非出于制定互联网标准的需要,在这种情况下,必须遵循互联网标准过程中定义的版权程序,或根据需要将其翻译成英语以外的其他语言。

The limited permissions granted above are perpetual and will not be revoked by the Internet Society or its successors or assigns.

上述授予的有限许可是永久性的,互联网协会或其继承人或受让人不会撤销。

This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS 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.

本文件和其中包含的信息是按“原样”提供的,互联网协会和互联网工程任务组否认所有明示或暗示的保证,包括但不限于任何保证,即使用本文中的信息不会侵犯任何权利,或对适销性或特定用途适用性的任何默示保证。

Acknowledgement

确认

Funding for the RFC Editor function is currently provided by the Internet Society.

RFC编辑功能的资金目前由互联网协会提供。