这个文档讨论了TCP/IP互联网上拥塞控制的某些方面的问题。它旨在激发
人们对这个问题的思考和进一步的讨论。为了实现改良的拥塞控制而提出某些具
体建议时,这个文档并不具体制定任何标准。
引言
拥塞控制在复杂的网络中公认的问题。我们发现,国防部的网间网协议(IP),
一种纯数据报协议,和传输控制协议(TCP),一种传输层协议,当把它们一起使
用时轻易遭受不平常的拥塞问题,这是由在传输层和数据报层之间的相互作用而
引起的。非凡的,IP网关对于被我们称为“拥塞崩溃”的现象而言是脆弱的,
非凡是当这种网关连到大范围的不同带宽的网络上的时候。我们研究了防止拥塞
崩溃的方案。
由于这些协议在基于ARPANETIMP技术的网络上使用频繁,这些问题没有得
到普遍的熟悉。基于ARPANETIMP的网络通常有一致的带宽和完全相同的交换节
点,并且容量很大。对大多数TCP/IP主机和网络而言,盈余的容量以及IMP系
统控制主机传输量的能力已足以处理拥塞。然而,随着最近ARPANET分成两个互
连的网络以及连到ARPANET上的具有不同特性的其他网络的增长,IMP系统良性
特性中的可靠性已不足以答应主机迅速而可靠的通信。为了使网络成功的运转,
必须改善拥塞控制。
福特航空航天及通信股份有限公司,和它的总公司,福特汽车公司,经营着如
今实际存在的唯一一家私有的TCP/IP长距离网络。这个网络与四个网点相连(一
个在Michigan,两个在Galifornia,另一个在England),它们中的一些还有大规
模的本地网。这个网络交叉连接在ARPANET上但却使用它自己的长距离线路。福
特公司各网点之间通过私人租赁线路进行传输,包括一条专用的横渡大西洋的卫
星通讯线路。所有的交换节点都是没有点到点流量控制的纯IP报交换,并且所
有主机运行的软件都是由福特公司或它的子公司编写或者经他们大量修改的软
件。这个网络上的链接带宽变化很大,从1200到10,000,000bps。通常,我
们已经没有能力购买昂贵的ARPANET那样的额外的长距离带宽,而且我们的长距
离链接在高峰时期是超负荷的。几秒的传输时间在我们的网络里是如此的平常。
由于我们的纯数据报定向,负荷过重和带宽的大范围变化,我们不得不去解决
ARPANET/MILNET组织才刚开始熟悉到的问题。我们的网络对主机的TCP实现的
次最优性能很敏感,包括与我们的网络连接或断开。我们力图检查在不同条件下
的TCP性能,并且已经解决了一些TCP普遍存在的问题。在这里我们提出了两个
问题及其解决办法。许多TCP实现有这些问题;假如对于某个给定的TCP实现,
经过ARPANET/MILNET网关的吞吐量比经过一个单一的网络糟,那么很可能这个
TCP实现存在这些问题中的一个或两个。
拥塞崩溃
在我们开始讨论这两个具体问题及其解决办法之前,描述一下当这些问题没
有解决时会发生什么是妥当的。在负载较重的带有端到端重发机制的纯数据报网
络中,当交换节点拥塞时,网络上的往返时间增加,在网络上传输的数据报的数
量也增加了。这在轻负载下是正常的.只要在传输中仅有每个数据报的一个拷贝,
拥塞就在控制之中。一旦还没递送成功的数据报开始重传,潜在的严重问题就可
能会出现。
主机TCP的实现预期在增加的时间间隔内多次重传数据报,直到重传间隔
的某个时间上限已到。通常,这个机制足以防止严重的拥塞问题。虽然有更好的
自适应主机重传算法,但是网络上的意外负载能使往返时间的增长速度比发送方
估计的往返时间的更新更快。当一个新的大量数据传输时,这样的负载就产生了,
这样的文件传输开始填充一个大的窗口。假如这个往返时间超过了所有主机的最
大重传间隔,那么主机将开始向网络产生越来越多的同一数据报的副本。这时,
这个网络有了严重问题。最终在交换节点中所有可获得的缓冲将饱和,于是必须
丢失数据报。这时,被传送的这个数据报的往返时间到达它的最大值。主机多次
发送每个报文,最终每个报文的某个拷贝到达它的目的地。这就是拥塞崩溃。
这个状态是稳定的。一旦到达饱和点,假如选择包丢弃算法良好,网络将继
续运行在性能降低了的状态下。在这种状态下,每个包被传输几次,吞吐量将降
低到正常情况的几分之一。我们实验性地迫使我们的网络处于这样的状态并且观
察它的稳定性。往返时间可能变得很大以致于由于主机超时造成连接中断。
拥塞崩溃和不正常的拥塞通常不出现在ARPANET/MILNET系统中,因为这
些网络有足够大的超额容量。只要连接不经过IP网关,增强的主机流量控制机
制通常能防止拥塞崩溃,非凡是自从针对和纯ARPANET网情况相关的时间常量
很好地调整了TCP实现以来。然而,当TCP运行在ARPANET/MILNET上数据
报在网关被丢弃时,除了ICMP的源抑制报文外,没有什么基本的机制来防止拥
塞崩溃。一些运行不好的主机通过它们自身使网关拥塞并阻止其他主机通过是没
价值的。我们已经在ARPANET上的某些主机上(我们已私下与这些主机的治理
员交流过)重复观察到这个问题。
给网关添加额外的内存不能解决这个问题。添加的内存越多,在数据报被丢
弃之前往返时间变得越长。这样,拥塞崩溃的发生将被延迟,但当崩溃发生时,
网络中的更大的数据报分片将被复制,吞吐量将变得更糟。
两个问题
和TCP实现的技术有关的两个要害问题已经被观察到;我们称它们为短数
据报问题和源抑制问题。第二个问题正由几个实现方案着手解决,第一个问题通
常被(不正确地)认为已经被解决了。我们发现,一旦短数据报问题解决,源抑
制问题就变得更加轻易处理。因此,我们首先提出短数据报问题及其解决方案。
短数据报问题
这里有一个与短数据报相关的具体问题。当TCP用来传输来自键盘的单字
符信息时,典型的结果是为了传输一个字节的有用数据传输了41个字节的数据
报(1个字节的数据,40个字节的头文件)。这4000%的开销是令人讨厌的,但
在轻负载的网络里是可以容忍的。然而,在负荷过重的网络中,由这个开销引起
的拥塞能导致数据报的丢失和重传,以及在交换节点和网关中由于拥塞而造成传
输时间过大。事实上,吞吐量可能降低以致于TCP连接被异常中断。
这个典型的问题在20世纪60年代下半期在Tymnet网络中第一次被提出并
被广泛熟悉。那里所采用的解决办法是强行对每单位时间里所产生的数据报的数
量给定一个限制。这个限制是通过对短数据报延迟一个短的时间(200-500ms)
后再传输来实施的,以期可以在定时器到时之前另一个或两个字符到来并附加在
同一个数据报中。为了增加用户的可接受性,一个附加的特性是当一个控制字符
(比如回车字符)到来时,禁止时间延迟。
这个技术已经在NCPTelnet,X.25PADs和TCPTelnet中使用。它的优点是
易于理解和不难实现。它的缺点是很难给出一个使每个人满足的时限。一个在
10Mbps以太网上提供高速应答服务的时限太短以致于不能防止在有5秒往返时
间的高负荷的网络上的拥塞崩溃;相反,处理高负荷的网络的时限太长又会给以
太网的用户造成挫折感。
短数据报的解决方案
显然,一个自适应的方法是不难想到的。我们期望为自适应交互包的时限提
出一个建议方案,这个时限是在TCP所观察到的往返时间延迟的基础上的。然而
虽然这样一个机制确实能被实现,但它是不必要的。我们发现了一个简单且优化
的解决方案。
这个解决方案是,假如任何先前在连接上传输的数据仍没有被确认,那么来
自用户的输出数据到来时,禁止传输TCP数据段。这个限制是无条件的,没有定
时器,不需要测试收到的数据的大小,不需要其他条件。典型的实现只需要TCP
程序中的一两行程序。
乍看,这个解决方案好象意味着TCP行为的剧烈改变。但并非如此。最终它
很好地工作。让我们看看为什么是这样。
当一个用户向一个TCP连接写数据时,TCP收到一些数据。它可以保持这些
数据以便以后传送或者也可以立即送出一个数据包。假如它不立即传送,它将在
一个传入的数据包到来且改变了系统状态之后传送数据。可以有两种方式之一来
改变这种状态;这个到来的数据包确认远端主机收到数据,或者通告远端主机为
新数据提供的可用缓冲空间大小。(后者指“更新窗口”)。每次,此连接上的数
据到来时,TCP必须重新检查它的当前状态并可能会送出一些数据包。这样,当
我们忽略送出来自用户端的数据时,我们只是简单地延迟传输直到下一个来自远
端的主机的报文到来。报文总是很快就到来,除非这条连接之前是空闲的或者与
另一端的通信丢失。在第一种情况,即空闲连接,我们的方案将使用户在任何时
候向TCP连接写数据时送出数据包。这样,我们就不会在空闲连接时死锁。第二
种情况,远端主机失败,传送更多的数据都是无效的。注重,我们没有采取任何
措施来禁止正常的TCP重传逻辑,因此,丢失报文不是问题。
这个方案在不同条件下的性能测试表明这个方案可以在所有情况下工作。第
一个测试的情况是我们想解决面向字符的Telnet连接问题。让我们想象一下,
用户每200ms向TCP输出一个新的字符,并且这个连接要经过以太网,此以太网
的往返时间包括了50ms的软件处理时间。假如没有任何机制来防止短数据报的
拥塞,与每个字符对应的数据包将被送出,响应是最佳的。开销将是4000%,
但在以太网上可以接受的。而典型的定时器方案,每秒两个数据包的限制,将使
两个或三个字符在一个数据包中被传送。响应性能将降低,即使在高带宽的以太
网上也是没有用的。开销降到1500%,但在以太网上这是个不太好的替换方案。
而我们的方案,用户所敲击的每个字符将找到一条空闲的TCP连接,字符将马上
被传送,正如在无控制的情况一样。用户将不会感觉到延迟。这样,我们的方案
既可作为无控制的方案运行又可以提供比定时器方案更好的响应。
第二个测试的情况是同样的Telnet测试,但是测试是在有5秒往返时间的
长距离连接上。假如没有任何机制防止短数据包拥塞,25个数据包将在5秒内
被送出。这儿开销是4000%。用典型的定时器方案且同样是每秒2个数据包的限
制,将仍有10个数据包不能处理并引起拥塞。当然往返时间将不会因传送很多
的数据包而得到改善;通常,它会因数据包竞争行时间而变得更糟。这时开销降
到了1500%。然而,用我们的方案,来自用户的第一个字符将发现空闲的TCP连
接且立即传送。接下来的24个字符,以200ms的间隔从用户端到来,将等待远
端主机来的报文。当一个对第一个数据报的确认ACK在5秒末到来时,这24个
等待的字符封装到数据包中被传送出去。这样,我们的方案导致了在没有损失响
应时间的情况下开销减少到320%。用我们的方案响应时间通常因为数据包开销
减少而得到改善。拥塞将减少且往返时间延迟将显著下降。在这个情况中,我们
的方案明显优于其他方法。
我们对所有的TCP连接使用我们的方案,不仅仅是Telnet连接。让我们看
看用我们的方法为文件传输建立数据连接时将会发生什么。我们将再一次考虑到
这两个极端的情况。
象前面所提的一样,我们首先考虑以太网的情况。用户现在以512字节块的
大小按TCP所能接受的速度向TCP写数据。用户第一次向TCP写的数据启动传输;
我们的第一个数据报的大小将是512+40字节或552字节。用户的第二次写数据
不会引起传送但会使这个块被缓冲。设想用户在第一个确认到来之前填充TCP的
输出缓冲区。然后,当ACK到来时,满足窗口大小的所有排队数据将被送出,从
那时起,窗口保持为满,每个ACK开始一个传送循环,等待的数据被送出。这样,
在一个往返时间初始周期以后,只有一个块要传送时,我们的方案解决了最大吞
吐量的情况。由于启动延迟在以太网上只有50ms,因此,启动的瞬时延迟是无
关重要的。三种方案都对这种情况提供了等价的性能。
最后,让我们看看在有5秒往返时间的连接上的文件传输。在第一个确认回
来之前只有一个数据包被发送;窗口将被填充并填满。因为往返时间是5秒,只
有512字节的数据在第一个5秒被发送。假定有一个2k的窗口,一旦第一个确
认来到,2K的数据将被发送,之后,将保持每5秒2K的稳定速率。只有在这种
情况下我们的方案才比定时器方案差,差别只在启动瞬时。稳定状态下的吞吐量
是相同的。朴素的方案和定时器方案在上面所提的情况下都要花250秒来传输
100K字节的文件,我们的方案将花254秒,1.6%的差别。
带ICMP的拥塞控制
解决了短数据报问题以及在我们自己网络中的极端的短数据报拥塞问题,我
们把注重力转向通常的拥塞控制。既然我们的网络是没有点对点流量控制的纯数
据报网络,对我们而言,在IP标准下可获得的唯一机制是ICMP源抑制报文。在
精心的控制下,我们发现这足以防止严重的拥塞问题。我们发现留心主机或交换
节点对源抑制报文的行为是必要的。
何时发ICMP源抑制报文
当前的ICMP标准规定,无论何时包丢失,ICMP源抑制报文就应该被发送,
此外,当网关发现自己资源不足时也应发送源抑制报文。这里有些二义性,但很
明显,没有送ICMP报文而丢弃数据包违反了的标准。
我们的基本假设是,在网络正常运行时数据包不应该被丢弃。因此我们想在
发送方使交换节点和网关超负荷之前抑制发送方重发。我们的交换节点在缓冲区
耗尽之前能很好地发送ICMP源抑制报文;直到它们在发送ICMP源抑制报文之前
必须丢弃报文时才等待。正如我们在短数据报问题的分析中演示的,仅仅提供大
量的缓冲是不能解决问题的。通常,我们的经验是,当用了缓冲区的一半左右,
源抑制报文就应该发送了;这不是基于广泛的实验,但似乎是个合理的技术决定。
可以讨论一个自适应方案,这个方案可以调整基于近期经验的抑制产生边界;到
目前为止我们还没有发现这个必要性。
还有其他的网关实现算法,仅在不只一个包被丢弃之后才产生源抑制报文。
我们认为这种方法是不好的,因为任何基于包丢弃的拥塞控制系统浪费带宽,且
可能在负荷重时轻易受拥塞崩溃的影响。我们理解的是,被动地产生源抑制报文
的方案基于这样的担心,害怕确认传输将被抑制以及这将导致连接失败。正如下
面将要展示的,在主机实现中的恰当的源抑制控制排除了这种可能性。
在收到ICMP源抑制报文时做什么
当ICMP收到一个源抑制报文时我们通知TCP或者该层上的任意其他协议。
我们的TCP具体实现的基本行为是减少与源抑制报文中所指出的主机的连接上
未处理的数据的数量。使发送端TCP的反应就象远端主机窗口大小已经减少,从
而实施这个控制。我们的第一个实现过于简单化但却有效;一旦收到源抑制报文,
只要窗口不为空,我们的TCP就认为窗口大小为0并做相应处理。这个行为将持
续到收到一定数量(现在是10)的ACK为止,到那时,TCP回到正常的运行状态
。Linkabit公司的DavidMills在他的DCN系统中实现了一个类似的但更具体
的对未处理的数据包的节流控制。这个附加的复杂性好象提供了一个获得吞吐量
的方式,但我们没有做过正式的测试。两个实现都有效地防止了交换节点的拥塞
崩溃。
这样,源抑制方法有效地限制了到有限数量(可能为1)的未处理报文的连
接。因此,通信能继续但是速率降低,那正是期望的效果。
这个方案有个重要的性质,源抑制不能禁止确认和重传的发送。源抑制在
IP层上的完全实现通常是不成功的,因为IP缺少足够的信息来正确地控制一个
连接的流量。抑制确认信息往往产生重传和不必要的传输。抑制重传可能因重传
超时而使连接丢失。我们的方案将在服务器超负荷下保持活动连接但减少每个连
接的带宽。
在同一层与TCP一样的其他协议也应该响应源抑制。在每种情况下,我们建
议应该控制新的传输流量但正常对待确认。唯一严重的问题来自于用户数据报协
议,而通常不的主要传输发生器。我们仍未在这些协议中实现任何流量控制。
网关的自防御
正如我们已经显示的,网关易受拥塞治理不善的主机的攻击。由于产生过多
通信量而引起的主机错误行为不仅防止了主机自身的传输而且能影响了其他不
相关的传输。这个问题可以在主机级处理,但既然一台有故障的主机能影响其他
主机,将来的网关应该有防御能力使它们自己不被那些可恶可憎的主机的这种行
为所影响。我们提供了一些基本的自防御技术。
曾经在1983年下半年,一个在ARPANT主机中的TCP故障使主机以ARPANET
所能接受的速度疯狂地产生相同数据报的重发报文。通过ARPANET连接到我们网
络的网关饱和,既然这个网关到ARPANET的带宽比到我们网络的要宽,少量有用
的传输能通过。网关忙于发送源抑制报文但故障主机忽略它们。这持续了几个小
时,直到故障主机崩溃。在这期间,我们的网络有效地从ARPANET上断开。
当网关被迫丢弃一个数据包时,网关慎重地选择要丢弃的数据包。做这个决
定的典型技术是丢弃最近收到的数据包,或者数据包在最长的输出队列的末端。
我们提出一个值得的实用方法是,丢弃在网关中产生最多数据包的队列的对应主
机所产生的最近的数据包,这种策略有助于平衡使用这个网关的各主机间的吞吐
量。我们还没有尝试过这个策略,但它似乎是网关自保护的一个合理开始点。
另一个策略是丢弃新到来的数据包,假如这个数据包已经在队列中做了一个
拷贝。假如使用哈希技术,为实现这一检查的计算负荷就不是问题。这个检查不
能防止恶毒主机的攻击,但提供了一些保护措施来防止带低劣重传控制的TCP实
现。假如本地主机与本地网络很好地协调工作,那么在快速本地网与慢速长距离
网络之间的网关可以发现这个检查是有价值的。
理想的情况是网关应该检测出故障主机并抑制它们;这样的检测在纯数据报
系统中是困难的。虽然,对ICMP源抑制报文的响应失败应该被认为是网关与主
机断开的依据。检测这样的失效是重不平常的但它是一个值得进一步研究的领
域。
结论
与纯数据报网络相关的拥塞控制问题是困难的,但有效的解决办法是存在
的。假如TCP/IP在重负荷下运行,TCP实现算法必须以至少和这里描述过的解
决方法一样有效的方式来解决这几个要害的问题。
在纯ARPANET网中没有这个问题,因为当没有处理的数据包过多时,IMP机制将封锁主
机,但在这种情况下,涉及到纯数据报本地网(比如以太网)或者一个纯数据报网关(比如
ARPANET/MILNET网关),有大量的小数据报未处理是有可能的。
ARPANETRFC792是当前的标准。国防通讯部门通告我们,在MIL-STD-1777
中的ICMP描述是不完全的,且在这个标准将来的修订版中将被删除。
这点遵从控制学的观点“不要受比例控制的干扰除非它不工作了。”