T/TCP:用于事务的 TCP
T/TCP 是 TCP 协议的一个实验性扩展。它旨在解决 TCP/IP 协议栈中对基于事务的传输协议的需求。
TCP 和 UDP 是目前可用于基于事务的应用程序的选择。TCP 可靠但对于事务来说效率低下,而 UDP 不可靠但效率很高。T/TCP 介于这两种协议之间,使其成为某些应用程序的替代方案。
目前,有几种 UNIX 版本支持 T/TCP。SunOS 4.1.3(一种基于 Berkeley 的内核)是 T/TCP 的最早实现,于 1994 年 9 月发布。下一个实现是 FreeBSD 2.0,于 1995 年 3 月发布。在我的毕业设计项目中,我于 1998 年 4 月在利默里克大学为 Linux 实现了 T/TCP。源代码可在 http://www.csn.ul.ie/~heathclf/fyp/ 获取。
在本文中,我将讨论 T/TCP 的操作、优点和缺点。这将使应用程序开发人员能够决定何时 T/TCP 适合网络应用程序。我将展示我对 T/TCP 和 TCP 之间进行比较分析的结果,该分析基于每个事务的会话数据包数量。我还将给出我对 T/TCP 对万维网可能产生的影响的案例研究的结论。
TCP/IP 参考模型是计算机上网络协议栈的规范。它的存在是为了为网络开发人员提供共同的基础。这使得不同供应商提供的网络更容易互连。
参考模型中传输层最流行的实现是传输控制协议 (TCP)(一种面向连接的协议)和用户数据报协议 (UDP)(一种无连接的协议)。
这两种协议都有优点和缺点。协议的两个主要方面使其在不同领域很有用。UDP 是一种无连接协议,因此不可靠但速度快,适用于 DNS(域名系统)等应用程序,在这些应用程序中,速度比可靠性更重要。另一方面,TCP 是一种可靠的、面向连接的协议。因此,TCP 比 UDP 慢。
随着近年来互联网的爆炸式增长,对新规范的需求应运而生。当前的传输协议要么过于冗长,要么不够可靠。需要一种比 TCP 更快但比 UDP 更可靠的协议。这种新协议可以减少带宽并提高数据传输速度,这在目前非常需要。
用于事务的 TCP (T/TCP) 可能是 TCP 和 UDP 的后继者。它是一种面向事务的协议,基于最小的段传输,因此它没有与 TCP 相关的速度问题。通过构建在 TCP 之上,它没有与 UDP 相关的不可靠问题。考虑到这一点,RFC1379 于 1992 年 11 月发布。它讨论了扩展 TCP 协议以允许面向事务的服务的概念。RFC 讨论的一些主要点包括绕过三次握手并将 TIME-WAIT 状态从 240 秒缩短到 12 秒。十八个月后,RFC1644 发布,其中包含事务 TCP 的规范。T/TCP 减少了当前 TCP 协议完成的许多不必要握手和错误检测,因此,提高了连接速度并减少了必要的带宽。
术语“事务”是指客户端发送给服务器的请求,以及服务器的回复。RFC955 列出了事务处理应用程序的一些常见特征
非对称模型:两个端点扮演不同的角色;这是一种典型的客户端-服务器角色,客户端请求数据,服务器响应。
持续时间短:通常,事务运行的时间跨度很短。
数据包少:每个事务都是对少量信息的请求,而不是双向大量信息的传输。
互联网的增长给网络的带宽和速度带来了压力。现在的用户比以往任何时候都多,需要更有效的数据传输形式。
事务中所需的最少数据包数是两个:一个请求,后跟一个响应。UDP 是 TCP/IP 协议栈中唯一允许这样做的协议,但问题是传输的不可靠性。
T/TCP 具有 TCP 的可靠性,并且非常接近实现 2 个数据包交换(实际上是三个)。T/TCP 使用 TCP 状态模型进行数据计时和重传,但引入了一种新机制来减少数据包。
即使使用 T/TCP 发送了三个数据包,数据也承载在前两个数据包中,从而允许应用程序以与 UDP 相同的速度查看数据。第三个数据包是客户端对服务器的确认,表明它已收到数据,这就是 TCP 可靠性的体现方式。
考虑一个 DNS 系统,客户端向服务器发送请求并期望返回少量数据。事务的图示如图 1 所示。该图与 UDP 请求非常相似,与 TCP 相比,数据包传输量节省了 66%。显然,在传输大量数据的情况下,将传输更多的数据包,因此节省的百分比会降低。
计时实验表明,T/TCP 所需的时间比 UDP 略长,但这是计算机速度而不是网络速度的结果。随着计算机变得越来越强大,T/TCP 的性能将接近 UDP 的性能。
TCP 加速打开 (TAO) 是 T/TCP 引入的一种机制,旨在减少与主机建立连接所需的数据包数量。
T/TCP 引入了许多新选项。这些选项允许使用 TAO 与主机建立连接。T/TCP 使用一个 32 位化身编号,称为连接计数 (CC)。此选项在 T/TCP 段的选项部分中携带(参见图 2)。为打开连接的每个方向分配一个不同的 CC 值。增量 CC 值分配给主机建立的每个连接,无论是主动还是被动。
使用 CC 值绕过三次握手。每个服务器主机缓存它从每个不同的客户端主机收到的最后一个有效 CC 值。此 CC 值与初始 SYN 段一起发送到服务器。如果特定客户端主机的初始 CC 值大于相应的缓存值,则 CC 选项的属性(递增的数字)确保 SYN 段是新的并且可以立即接受。
如果 SYN 段中到达的 CC 选项小于主机缓存的最后接收的 CC 值,或者发送了 CCnew 选项,则 TAO 测试失败。然后,服务器以正常的 TCP/IP 方式启动三次握手。
T/TCP 可能对当前使用 TCP 或 UDP 的某些应用程序有利。目前,许多应用程序是基于事务的而不是基于连接的,但仍然必须依赖 TCP,以及开销。UDP 是另一种选择,但由于协议中没有内置超时和重传,这意味着应用程序程序员必须自己提供超时和可靠性检查。由于 T/TCP 是基于事务的,因此没有设置和关闭时间,因此可以以最小的延迟将数据传递给进程。
超文本传输协议是万维网用于访问网页的方法。T/TCP 可用于减少所需的数据包数量。
使用 TCP,事务是通过连接到服务器(三次握手)、请求文件 (GET 文件),然后关闭连接(发送 FIN 段)来完成的。T/TCP 的操作方式是在一个段 (TAO) 中连接到服务器、请求文档并关闭连接。显然,这种方法节省了带宽。
远程过程调用 (RPC) 也遵循事务风格范例。客户端向服务器发送请求,要求服务器运行一个函数。函数的结果然后在回复中返回给客户端。使用 RPC 传输的数据量很少。
域名系统用于将主机名解析为定位主机的 IP 地址。
要解析域名,客户端会向服务器发送包含 IP 地址或主机名的请求。服务器会回复相应的主机名或 IP 地址。此协议使用 UDP。
由于使用了 UDP,因此该过程速度很快,但不可靠。此外,如果服务器的响应超过 512 字节的数据,它会将数据连同前 512 字节和一个截断标志一起发送回客户端。客户端必须使用 TCP 重新提交请求。
原因是无法保证接收主机能够重新组装超过 576 字节的 IP 数据报。为了安全起见,许多协议将用户数据限制为 512 字节。
T/TCP 是 DNS 协议的完美候选者。它可以以接近 UDP 的速度进行通信,并且具有 TCP 的可靠性。
为了研究 T/TCP 实现的优势,重要的是测试其操作,并将其操作与原始 TCP/IP 操作进行比较。我使用带有 T/TCP 修改的 Linux 2.0.32 内核和已经实现 T/TCP 的 FreeBSD 2.2.5 版本执行了这些测试。
为了研究 T/TCP 与原始 TCP/IP 相比的性能,我编译了许多可执行文件,这些文件向客户端返回不同大小的数据。涉及的两台主机是运行 Linux 的 elendil.ul.ie 和运行 FreeBSD 2.2.5 的 devilwood.ece.ul.ie。执行了十种不同响应大小的测试,以便改变返回完整响应所需的段数。每个请求发送 50 次,结果取平均值。每种情况下的最大段大小为 1460 字节。
用于性能评估的指标是每个事务的平均段数。我使用 Tcpdump 来检查交换的数据包。请注意,Tcpdump 并非完全准确,因为在快速数据包交换期间,它倾向于丢弃一些数据包以跟上速度。这解释了结果中的一些差异。
图 3 显示了 T/TCP 的段数测试结果与正常 TCP/IP 的段数测试结果。显而易见的是,平均节省了五个数据包。这五个数据包在三次握手中以及发送以关闭连接的数据包中得到解释。丢失的数据包和重传导致了图表路径中的差异。

图 3. 段数与数据传输大小的关系
关于使用 TCP 客户端和 T/TCP 服务器时段数的平均值的一个有趣的点是,仍然节省了一个段。正常的 TCP 事务需要九个段,但由于服务器使用了 T/TCP,FIN 段被捎带在最终数据段上,从而将段数减少了一个。这表明即使只有一方了解 T/TCP,段数也会减少。
图 4 显示了不同数据包大小的百分比节省量。节省的数据包数量保持相当恒定,但由于交换的数据包数量增加,总体节省量有所下降。这表明 T/TCP 对小数据交换更有利。

图 4. 每个数据传输大小的百分比节省量
实现中的主要内存消耗是在路由表中。在 Linux 中,对于主机与之联系的每台计算机,都会在路由表中为外部主机创建一个条目。这适用于直接连接和多跳路由。此路由表通过 rtable 结构访问。T/TCP 的实现向该结构添加了两个新字段,CCrecv 和 CCsent。
此结构的整个大小为 56 字节,这在小型独立主机上不是主要的内存占用。但是,在繁忙的服务器上,主机每小时可能与数千台其他主机通信,这可能会对内存造成很大的压力。Linux 有一种机制,可以从内存中删除不再使用的路由。定期运行检查以清除未使用的路由以及已空闲一段时间的路由。
这里的问题是路由表保存了 TAO 缓存。因此,每当删除包含来自主机的最后一个 CC 值的路由时,本地主机都必须使用 CCnew 段重新启动三次握手。
永久保留路由条目的好处是显而易见的。最可能的用途是在主机仅与一组特定的外部主机通信并拒绝访问未知主机的情况下。在这种情况下,在内存中保留永久记录是有利的,这样可以更频繁地绕过三次握手。
原始协议规范 (RFC1644) 将 T/TCP 标记为实验性协议。自从 RFC 发布以来,还没有对协议进行更新以修复一些问题。从前面的章节来看,相对于原始 TCP 协议的优势是显而易见的,但缺点是否超过了优点呢?
T/TCP 的更严重问题之一是它使主机容易受到某些拒绝服务攻击。SYN 洪水(有关更多信息,请参见 www.sun.ch/SunService/technology/bulletin/bulletin963.html)是指一种拒绝服务攻击形式,攻击者不断向主机发送 SYN 数据包。主机为每个 SYN 创建一个 sock 结构,从而减少了可以提供给合法用户的 sock 结构数量。当使用了足够的内存时,这最终可能导致主机崩溃。SYN Cookie 在 Linux 内核中实现,以对抗这种攻击。SYN Cookie 会导致 T/TCP 出现问题,因为 Cookie 中没有发送 TCP 选项,并且无法立即使用初始 SYN 中到达的任何数据。T/TCP 中的 CC 选项本身确实提供了一些保护,但安全性不够。
研究期间发现的另一个严重问题是攻击者可以绕过 rlogin 身份验证。攻击者创建一个数据包,其中包含一个虚假的 IP 地址,该地址是目标主机已知的地址。当发送数据包时,CC 选项允许立即接受该数据包并将数据传递出去。然后,目标主机向原始 IP 地址发送 SYNACK。当此 SYNACK 到达时,原始主机发送重置,因为它不处于 SYN-SENT 状态。这种情况发生得太晚了,因为命令已经会在目标主机上执行。任何使用 IP 地址作为身份验证的协议都容易受到此类攻击。(请参见 geek-girl.com/bugtraq/1998_2/0020.html。)
但是,应该注意的是,将 T/TCP 与 HTTP 等协议结合使用,安全问题较少,因为无法使用 HTTP 运行任何服务器命令。
RFC1644 还有一个重复事务问题。对于非幂等应用程序(非常不希望重复事务),这可能是严重的。如果向服务器发送请求并且服务器处理了事务,但在发送回确认之前,进程崩溃,则 T/TCP 中可能会发生此错误。客户端超时并重新传输请求;如果服务器进程及时恢复,则可以重复相同的事务。发生此问题的原因是 SYN 中的数据可以立即传递给进程,而不是在 TCP 中,在 TCP 中,必须先完成三次握手才能使用数据。使用两阶段提交和事务日志记录可以消除此问题。
由于万维网是当今客户端-服务器事务处理的主要示例,因此本节将重点介绍 T/TCP 对 Web 性能的好处。
目前,HTTP 协议位于 TCP/IP 参考模型的应用层。它使用 TCP 协议来执行其所有操作,UDP 协议太不可靠。信息传输中涉及很多延迟,即三次握手和显式关闭交换。
在 Inktomi 网络爬虫搜索引擎搜索的 260 万个 Web 文档的调查中(请参见 http://inktomi.berkeley.edu/),发现 Web 上文档的平均大小为 4.4KB,中位大小为 2.0KB,遇到的最大大小为 1.6MB。
参考图 4,可以看出段大小越小,T/TCP 相对于正常 TCP/IP 的性能就越好。文档平均大小为 4.4KB,这使得数据包数量平均节省了 55% 以上。考虑到中位大小,节省量约为 60%。
在他们的论文“HTTP/1.1、CSSI 和 PNG 的网络性能影响”(请参见资源)中,作者研究了将压缩引入 HTTP 协议的效果。他们发现压缩使下载速度提高了 64%,所需的数据包数量减少了 68%。相对于正常的 TCP/IP,这使数据包交换和数据大小降低到 T/TCP 变得有利的水平。因此,涉及压缩和 T/TCP 的策略可以大大节省时间和带宽。
在这种情况下,增量是指两个文件之间的差异。在 UNIX 系统上,可以使用 diff 命令生成两个文件之间的增量。使用更改的文件和增量,可以再次重新生成原始文件,反之亦然。
JC Mogul 等人。(请参见资源)研究了增量编码对 Web 的影响。在他们的测试中,他们不仅使用了增量编码,还压缩了生成的增量,以进一步减少传输的信息量。他们发现,通过使用 vdelta 增量生成器和压缩,他们可以将数据传输的节省量提高到 83%。
如果将此方法与 T/TCP 一起使用,则数据包传输量可能会进一步节省 66%。数据包传输量总共减少了 94%。
但是,应该注意的是,这是最佳情况。在这种情况下,文档将已缓存在服务器端和客户端,并且客户端和服务器先前已完成三次握手,以便于 TAO 测试。
使用套接字编程为 T/TCP 编程略有不同。例如,实现 TCP 客户端的系统调用链如下:
socket:创建套接字。
connect:连接到远程主机。
write:将数据写入远程主机。
shutdown:关闭连接的一侧。
而使用 T/TCP,命令链将是:
socket:创建套接字。
sendto:连接、发送数据并关闭连接。sendto 函数必须能够使用新的标志 MSG_EOF 来指示内核它没有更多数据要在此连接上发送。
对 T/TCP 的分析表明,它更有利于小型、面向事务的传输,而不是大规模的信息传输。在万维网、远程过程调用和 DNS 等案例中可以看到事务的各个方面。这些应用程序可以从 T/TCP 的使用中受益,从而提高效率和速度。T/TCP 平均减少了事务中涉及的段数和完成事务所需的时间。
由于 T/TCP 仍然是一种实验性协议,因此存在一些需要解决的问题。遇到的安全问题包括容易受到 SYN 洪水攻击和 rlogin 身份验证绕过的攻击。操作问题包括可能发生重复事务。不太常见的问题是高速连接上 CC 值的回绕,从而使目标主机容易接受错误连接上的段。
许多人认识到需要一种有利于事务式处理的协议,并愿意接受 T/TCP 作为答案。安全考虑因素导致得出结论,T/TCP 在受控环境中更有用,在这种环境中,来自可能利用标准弱点的潜在攻击者的危险很小。封闭环境的示例包括公司内联网和受防火墙保护的网络。许多公司将 Web 视为开展业务(内部和外部)的未来,因此采用 T/TCP 和 HTTP 的一些改进(例如压缩和增量编码)的系统将大大提高公司内联网的速度。
如果程序员愿意接受 T/TCP 作为其应用程序的解决方案,则只需对应用程序进行少量修改即可使其了解 T/TCP。对于客户端编程,它涉及消除 connect 和 shutdown 函数调用,这些调用可以替换为向 sendto 命令添加 MSG_EOF 标志。服务器端修改仅涉及向 send 函数添加 MSG_EOF 标志。
对 T/TCP 的研究表明,它是一种几乎准备就绪但尚未完全准备好接管通用事务处理的协议。对于 T/TCP 本身,还需要做更多的工作来进一步开发它并解决安全和操作问题。可以使用其他身份验证协议(例如 Kerberos 和 IPv6 的身份验证功能)来解决安全问题。可以通过在将使用 T/TCP 的应用程序中构建更高的事务可靠性(例如两阶段提交和事务日志)来解决操作问题。
应用程序可以轻松修改为在 T/TCP 可用时使用它。任何涉及打开-关闭连接的应用程序都可以有效地使用 T/TCP,更突出的示例是 Web 浏览器、Web 服务器和 DNS 客户端-服务器应用程序。在较小程度上,time、finger 和 whois 等应用程序也可以从 T/TCP 中受益。许多网络实用程序都可以利用该协议的效率。所需要的只是去做它的动力。
但是,也许更紧迫的任务是将 T/TCP 代码移植到新的 Linux 内核系列 2.3。x。

Ivan Griffin
John Nelson