传输控制协议(TCP)是互联网协议组的主要协议之一。它起源于最初的网络实施,在网络实施中,它补充了互联网协议。因此,整个套件通常被称为TCP/IP。TCP在通过IP网络通信的主机上运行的应用程序之间提供可靠、有序且经过错误检查的八位字节流传递。万维网、电子邮件、远程管理和文件传输等主要互联网应用都依赖于TCP。不需要可靠数据流服务的应用程序可以使用用户数据报协议(User Datagram Protocol ,UDP),该协议提供无连接数据报服务,强调降低延迟而不是可靠性。
传输控制协议在应用程序和互联网协议之间提供中间级别的通信服务。它在互联网模型的传输层提供主机到主机的连接。应用程序不需要知道通过链路向另一台主机发送数据的特定机制,例如容纳传输介质的最大传输单位所需的IP分段。在传输层,TCP处理所有握手和传输细节,并通常通过网络套接字接口呈现到应用程序的网络连接抽象。
在协议栈的较低层,由于网络拥塞、流量负载平衡或不可预测的网络行为,IP数据包可能会丢失、复制或无序传送。TCP检测这些问题,请求重新传输丢失的数据,重新排列无序数据,甚至帮助最小化网络拥塞,以减少其他问题的发生。如果数据仍未送达,将通知数据源产生故障。一旦TCP接收器重组了最初发送的八位字节序列,它就将它们传递给接收应用程序。因此,TCP从底层网络细节中抽象出应用程序的通信。
许多互联网应用广泛使用TCP,包括万维网、电子邮件、文件传输协议、安全外壳、对等文件共享和流媒体。
TCP针对准确传递而不是及时传递进行了优化,并且在等待无序消息或丢失消息的重新传输时会导致相对较长的延迟(秒级延迟)。因此,它并不特别适合实时应用,如基于IP的语音通信。对于这类应用,通常推荐使用在用户数据报协议上运行的实时传输协议(RTP)等协议。[3]
TCP是一种可靠的流传输服务,它保证接收到的所有字节都是发送的字节顺序相同的。由于许多网络的数据包传输不可靠,所以TCP使用一种称为“带重传的肯定认答”技术来实现这一点。这要求接收器在接收数据时用确认消息进行响应。发送方保留其发送的每个数据包的记录,并从数据包发送时起维护计时器。如果计时器在接收到确认之前到期,发送方会重新发送数据包。如果数据包丢失或损坏,则需要计时器来预防这种现象的发生。[3]
虽然IP处理数据的实际传递,但它会追踪数据段,即消息被分成的各个数据传输单元,以便通过网络进行有效路由。例如,当网页服务器发送一个超文本标记语言文件时,该服务器的传输控制协议软件层将文件分成若干段,并分别转发给网络堆栈中的互联网层。互联网层软件通过添加一个包含(除其他数据外)目的地址的报头,将每个TCP段封装成一个数据包。当目标计算机上的客户端程序接收到这些数据时,传输层的TCP软件会重新组装这些数据段,并在将文件内容流式传输到接收应用程序时确保这些数据段的顺序正确无误。
传输控制协议接受数据流中的数据,将其分成块,并添加一个TCP头来创建TCP段。然后,TCP段被封装到互联网协议数据报中,并与对等方交换。[4]
术语“数据包”出现在非正式用法和正式用法中,而在更精确的术语中,段指的是“数据包协议数据单元”,数据包[5] 指的是“数据包协议数据单元”,帧指的是“数据链路层数据单元”。
进程通过调用TCP并传递数据缓冲区作为参数来传输数据。传输控制协议将这些缓冲区中的数据打包成段,并调用互联网模块将每个段传输到目的地传输控制协议。[6]
一个TCP段由一个段头和一个数据段组成。TCP报头包含10个必填字段和一个可选扩展字段(选项,表格中的粉红色背景)。
数据部分跟在标题后面。它的内容是为应用程序携带的有效载荷数据。数据段的长度没有在TCP段头中指定。它可以通过从总的IP数据报长度(在IP报头中指定)中减去TCP报头和封装IP报头的组合长度来计算。
Offsets | Octet | 0 | 1 | 2 | 3 | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Octet | Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
0 | 0 | Source port | Destination port | ||||||||||||||||||||||||||||||
4 | 32 | Sequence number | |||||||||||||||||||||||||||||||
8 | 64 | Acknowledgment number (if ACK set) | |||||||||||||||||||||||||||||||
12 | 96 | Data offset | Reserved 0 0 0 |
NS | CWR | ECE | URG | ACK | PSH | RST | SYN | FIN | Window Size | ||||||||||||||||||||
16 | 128 | Checksum | Urgent pointer (if URG set) | ||||||||||||||||||||||||||||||
20 ... |
160 ... |
Options (if data offset > 5. Padded at the end with "0" bytes if necessary.) ... |
TCP协议操作可以分为三个阶段。在进入数据传输阶段之前,必须在多步骤握手过程(连接建立)中正确建立连接。数据传输完成后,连接终端关闭已建立的虚拟电路并释放所有分配的资源。
TCP连接由操作系统通过一个编程接口来管理,该接口表示通信的本地端点,即互联网套接字。在TCP连接的生命周期内,本地端点会经历一系列状态变化:[13]
为了建立连接,TCP使用三次握手。在客户端尝试与服务器连接之前,服务器必须首先绑定并侦听端口以打开它进行连接:这称为被动打开。一旦被动打开被建立,客户端可以启动主动打开。要建立连接,需要进行三次(或三步)握手:
此时,客户端和服务器都已收到连接确认。步骤1、2为一个方向建立连接参数(序列号),并得到确认。步骤2、3为另一个方向建立连接参数(序列号),并得到确认。通过这些,建立了全双工通信。
连接终止阶段使用四次握手,连接的每一侧都独立终止。当一个端点希望停止它那一半的连接时,它发送一个FIN数据包,另一端用ACK来确认此FIN包。因此,典型的拆卸需要来自每个TCP端点的一对FIN和ACK段。在发送第一个FIN的一方应答了最后一个ACK后,在关闭连接之前等待超时,此时本地端口对于新连接不可用;这防止了由于在后续连接期间传送延迟的数据包而造成的混乱。
一个连接可以是“半开”的,在这种情况下,一方终止了它的末端,而另一方没有。已经终止的一方不能再向连接发送任何数据,但另一方可以。终止端应该继续读取数据,直到另一端也终止。
也可以通过三次握手来终止连接,即主机甲发送确认信息,主机乙回复确认信息(仅将两个步骤合并为一个步骤),主机甲回复确认信息。[14]
一些主机TCP堆栈可能会实现半双工关闭序列,就像Linux或惠普HP-UX那样。如果这样的主机主动关闭连接,但仍未读取堆栈已经从链路接收到的所有传入数据,该主机将发送一个RST而不是FIN(RFC 1122中的4.2.2.13部分)。这允许一个TCP应用程序确保远程应用程序已经读取了前者发送的所有数据——当它主动关闭连接时,从远程端等待FIN。但是远程TCP堆栈无法区分连接中止的RST和数据丢失的RST。这两种情况都会导致远程堆栈丢失接收到的所有数据。
对于应用协议开/关握手,一些使用TCP开/关握手的应用协议可能会在主动关闭时发现RST问题。例如:
s = connect(remote); send(s, data); close(s);
对于如上所述的程序流,如果未读数据已经到达了这一端,如上所述的TCP/IP堆栈不能保证所有数据都到达了另一个应用程序。
大多数实现都会在表中分配一个条目,该条目将会话映射到正在运行的操作系统进程。因为TCP数据包不包含会话标识符,所以两个端点都使用客户端的地址和端口来标识会话。每当收到数据包时,TCP实现必须在该表上执行查找,以找到目标进程。表中的每个条目称为传输控制块或传输控制块。它包含有关端点(IP和端口)、连接状态、正在交换的数据包的运行数据以及用于发送和接收数据的缓冲区的信息。
服务器端的会话数量仅受内存限制,并且会随着新连接的到达而增加,但是客户端必须在向服务器发送第一个SYN之前分配一个随机端口。该端口在整个会话过程中保持分配状态,并且有效地限制了来自每个客户端的IP地址的传出连接数。如果应用程序无法正确关闭不需要的连接,客户端可能会耗尽资源,甚至无法从其他应用程序建立新的TCP连接。
两个端点还必须为未确认的数据包和已接收(但未读)的数据分配空间。
除了用户数据报协议之外,TCP还有几个关键特性:
可靠传输
TCP使用序列号来标识数据的每个字节。序列号会标识从每台计算机发送的字节顺序,而不管在传输过程中可能发生的任何分组重新排序或分组丢失,都可以按顺序重构数据。第一个字节的序列号由发送方为标记为SYN的第一个数据包选择的。这个序列号可以是任意的,事实上,它应该是不可预测的,以抵御TCP序列预测攻击。
数据接收者发送带有序列号的确认(AcS),告知发送者数据已被接收到指定字节。确认并不意味着数据已经交付给应用程序。它们仅仅表示现在由接收者负责数据的传递。
可靠性是通过发送方检测丢失的数据并重新发送来实现的。TCP使用两种主要技术来识别丢失。重传超时(缩写为RTO)和重复累积确认(DupAcks)。
基于Dupack的重传
如果流中的单个包(比如包100)丢失,那么接收器不能确认大于100的包,因为它使用累积ACK。因此,接收机在接收到另一个数据分组时再次确认分组99。这种重复确认被用作丢包信号。也就是说,如果发送方收到三个重复的确认,它会重新发送最后一个未确认的数据包。使用阈值3是因为网络可能会重新排序数据包,导致重复确认。这个阈值已经被证明可以避免由于重新排序而导致的虚假重传。[16] 有时选择性确认(SACKs)被用来给出更明确的关于哪些数据包已经被接收的反馈。这大大提高了传输控制协议重发正确数据包的能力。
基于超时的重传
无论何时发送数据包,发送方都会设置一个计时器,该计时器是对数据包何时被确认的保守估计。如果发送方届时没有收到确认,它将再次发送该数据包。每次发送方收到确认时,计时器都会重置。这意味着只有当发送方长时间没有收到确认时,重发计时器才会触发。通常定时器值被设置为 其中 是时钟粒度。[17] 此外,如果重发定时器已经启动,但仍然没有接收到确认,则下一个定时器被设置为前一个值的两倍(直到某个阈值)。其中,这有助于抵御中间人拒绝服务攻击,这种攻击试图欺骗发送方进行如此多的重传,以至于接收方不堪重负。
如果发送方使用上述两种技术中的一种推断出数据已经在网络中丢失,它将重新发送数据。
误差检测
序列号允许接收者丢弃重复的数据包,并对重新排序的数据包进行正确排序。确认允许发送方决定何时重发丢失的数据包。
为确保正确性,包含校验和字段;有关校验和计算的详细信息,请参见校验和计算部分。按照现代标准,TCP校验和是一种弱校验。具有高误码率的数据链路层可能需要额外的链路纠错/检测能力。弱校验和通过在第2层(在TCP和IP之下,例如在PPP或以太网帧中使用)通常使用CRC或更好的完整性检查来部分补偿弱校验和。然而,这并不意味着16位的TCP校验和是冗余的:值得注意的是,在受CRC保护的跳之间的数据包中引入错误是常见的,但是端到端的16位的TCP校验和捕获了大多数这些简单的错误。[18] 这是工作中的端到端原则。
流控制
传输控制协议使用端到端的流量控制协议,以避免发送方发送数据太快导致传输控制协议接收方无法可靠地接收和处理数据。在不同网络速度的机器进行通信的环境中,拥有流量控制机制是至关重要的。例如,如果电脑将数据发送到正在缓慢处理接收数据的智能手机,智能手机必须调整数据流,以免被淹没。[3]
TCP使用滑动窗口流量控制协议。在每个TCP段中,接收器在接收窗口字段中指定它愿意为连接缓冲的额外接收的数据量(以字节为单位)。在必须等待接收主机的确认和窗口更新之前,发送主机只能发送该数量的数据。
当接收方通告窗口大小为0时,发送方停止发送数据并启动持续计时器。持续计时器用于保护TCP免受死锁情况的影响,如果来自接收方的后续窗口大小更新丢失,并且发送方在收到来自接收方的新窗口大小更新之前无法发送更多数据,则可能会出现死锁情况。当持续定时器到期时,传输控制协议发送方通过发送一个小数据包来尝试恢复,以便接收方通过发送另一个包含新窗口大小的确认来响应。
如果接收器正在以小增量处理输入数据,它可能会重复通告一个小的接收窗口。这被称为愚蠢窗口综合征,因为考虑到相对较大的传输控制协议报头开销,在一个传输控制协议段中只发送几个字节的数据是低效的。
拥塞控制
TCP的最后一个主要方面是拥塞控制。TCP使用多种机制来实现高性能并避免拥塞崩溃,因为拥塞崩溃会导致网络性能下降几个数量级。这些机制控制数据进入网络的速率,保持数据流低于触发崩溃的速率。它们还在流量之间产生近似最大-最小的公平分配。
发送方使用对发送数据的确认或缺乏确认来推断TCP发送方和接收方之间的网络状况。与定时器相结合,TCP发送器和接收器可以改变数据流的行为。这通常被称为拥塞控制和/或网络拥塞避免。
TCP的现代实现包含四种相互交织的算法:慢启动、拥塞避免、快速重传和快速恢复(RFC 5681)。
此外,发送方使用基于发送方和接收方之间的估计往返时间(或RTT)以及该往返时间的差异的重传超时(RTO)。RFC 6298规定了该定时器的行为。对RTT的估计有些微妙之处。例如,发送方在计算重传数据包的RTT样本时必须小心;通常他们使用卡恩( Karn)算法或TCP时间戳(见RFC 1323)。这些单独的RTT样本随时间平均,使用雅各布森(Jacobson)算法创建平滑往返时间(SRTT)。这个SRTT值最终被用作往返时间估计值。
增强传输控制协议以可靠地处理丢失、最小化错误、管理拥塞并在非常高速的环境中快速运行是正在进行的研究和标准开发领域。因此,有许多不同的TCP拥塞避免算法。
最大数据段大小是指TCP在单个数据段中愿意接收的最大数据量,以字节为单位。为了获得最佳性能,MSS应设置得足够小,以避免可能导致数据包丢失和过度重传的IP碎片。为了实现这一点,通常在建立TCP连接时,由每一方使用MSS选项来声明MSS,在这种情况下,MSS是从发送方和接收方直接连接的网络的数据链路层的最大传输单元(MTU)大小得出的。此外,TCP发送方可以使用路径MTU发现来推断发送方和接收方之间沿网络路径的最小MTU,并使用该最小MTU来动态调整MSS以避免网络内的IP碎片。
MSS声明也经常被称为“MSS协商”。严格地说,发起方和接收方之间没有“协商”台,因为这意味着发起方和接收方将协商并同意适用于连接两个方向上所有通信的单一的、统一的MSS。事实上,对于一个TCP连接中的两个数据流方向,允许两个完全独立的MSS值。[19] 这种情况可能会出现,例如,如果参与连接的设备之一为处理传入的TCP段保留了极其有限的内存量(可能甚至小于已发现的总路径MTU)。
当数据包丢失时,完全依赖原始的TCP协议所采用的累积确认方案会导致效率低下。例如,假设序列号为1,000到10,999的字节在相同大小的10个不同的TCP段中发送,第二个段(序列号为2,000到2,999)在传输过程中丢失。在纯累积确认协议中,接收器只能发送累积确认值2,000(紧接在接收数据的最后一个序列号之后的序列号),并且不能说它成功地接收了字节3,000到10,999。因此,发送方可能必须重新发送从序列号2,000开始的所有数据。
为了缓解这一问题,TCP采用了选择性确认(SACK)选项,该选项在1996年的RFC 2018中定义,除了连续接收的最后一个连续字节的最后一个序列号之后的序列号之外,它还允许接收器确认正确接收的不连续分组块,就像基本的TCP确认一样。确认可以指定SACK块的数量,其中每个SACK块由块的左边缘(块的第一个序列号)和块的右边缘(紧接块的最后一个序列号的序列号)传送,块是接收器正确接收的连续范围。在上面的例子中,接收器将发送累积ACK值为2,000的确认段和序列号为3,000和11,000的SACK选项头。因此,发送方将仅重发序列号为2,000至2,999的第二段。
TCP发送方可以将无序的段传递解释为丢失的段。如果这样做,TCP发送方将重新发送无序数据包之前的数据段,并降低该连接的数据传输速率。重复SACK选项是2000年5月在RFC 2883中定义的SACK选项的扩展,它解决了这个问题。传输控制协议接收器发送一个数据确认来指示没有数据段丢失,然后传输控制协议发送器可以恢复较高的传输速率。
SACK选项不是强制性的,只有在双方都支持的情况下才生效。这是在建立连接时协商的。SACK使用了一个传输控制协议报头选项。SACK的使用已经变得广泛——所有流行的TCP栈都支持它。选择性确认也用于流控制传输协议(SCTP)。
为了更有效地使用高带宽网络,可以使用更大的TCP窗口大小。“TCP窗口大小”字段控制数据流,其值限制在2到65,535字节之间。
由于大小字段无法扩展,因此使用了缩放因子。如RFC 1323中定义的,TCP窗口缩放选项是用于将最大窗口大小从65,535字节增加到1gb的选项。扩展到更大的窗口大小是TCP调优所必需的一部分。
窗口缩放选项仅在TCP三次握手期间使用。窗口比例值代表向左移动16位窗口大小字段的位数。对于每个方向,窗口比例值可以独立地从0(无偏移)设置为14。双方都必须在其同步码段中发送选项,以便在任一方向上启用窗口缩放。
一些路由器和数据包防火墙会在传输过程中重写窗口比例因子。这导致发送方和接收方采用不同的TCP窗口大小。结果是流量不稳定,可能非常慢。该问题在有缺陷路由器后面的一些站点上是显而易见的。[20]
1992年在RFC 1323中定义的TCP时间戳可以帮助TCP确定数据包的发送顺序。TCP时间戳通常不与系统时钟对齐,而是从某个随机值开始。许多操作系统会为每经过一毫秒增加时间戳;然而,RFC只声明刻度应该是成比例的。
有两个时间戳字段:
TCP时间戳用于一种称为防止包装序列号或PAWS的算法中 (详见RFC 1323)。当接收窗口跨越序列号环绕边界时,使用PAWS。在数据包可能被重传的情况下,它会回答以下问题:“这个序列号是在前4 GB还是在后4GB?”时间戳被用来打破平局。
此外,Eifel检测算法(RFC 3522)使用TCP时间戳来确定重传是因为数据包丢失还是只是顺序错误。
最近的统计数据显示,时间戳的采用水平停滞在40%左右,原因是自2008年以来,windows服务器不再支持时间戳 [21]。
在Linux内核中默认启用了TCP时间戳。[22],并在2008、2012和2016年默认禁用。[23]
可以中断或中止排队的流,而不是等待流完成。这是通过将数据指定为紧急数据来实现的。这告诉接收程序立即处理它,以及其他紧急数据。完成后,TCP通知应用程序并恢复到流队列。例如,当TCP用于远程登录会话时,用户可以发送一个键盘序列,在另一端中断或中止程序。当远程机器上的程序无法正常运行时,最需要这些信号。必须在不等待程序完成当前传输的情况下发送信号。[3]
TCP带外数据不是为现代互联网设计的。紧急指针仅改变远程主机上的处理,而不加速网络本身上的任何处理。当它到达远程主机时,协议有两种稍微不同的解释,这意味着只有单字节的OOB数据是可靠的。这是假设它是可靠的,因为它是最不常用的协议元素之一,并且往往实现得很差。[24][25]
通常,传输控制协议要等待200毫秒才能发送完整的数据包(纳格勒(Nagle)算法试图将小消息分组到一个数据包中)。如果在文件传输过程中不断重复,这种等待会造成较小但潜在的严重延迟。例如,一个典型的发送块是4 KB,一个典型的MSS是1460,所以在10兆比特/秒的以太网上有2个数据包发出,每个需要大约1.2毫秒,然后第三个数据包在197毫秒的暂停后携带剩余的1176,因为TCP正在等待一个完整的缓冲区。
在telnet的情况下,每次用户击键都会在用户在屏幕上看到之前被服务器回显。这种延迟会变得非常烦人。
设置套接字选项TCP_NODELAY会覆盖默认的200毫秒发送延迟。应用程序使用这个套接字选项来强制在写入一个字符或一行字符后发送输出。
RFC将 PSH
推送位定义为“发送给接收方协议栈的消息,以便立即将该数据发送给接收方的应用程序”。[3] 使用伯克利( Berkeley sockets)套接字无法在用户空间中指示或控制它,它仅由协议栈控制。[26]
TCP可能会受到多种方式的攻击。对传输控制协议进行彻底安全评估的结果,以及对已发现问题的可能缓解措施,[27] 目前正在IETF内部进行研究。[28]
通过使用假冒的IP地址并重复发送带有目的性组装的同步数据包,然后发送许多确认数据包,攻击者可能会导致服务器消耗大量资源来跟踪假冒连接。这被称为SYN洪水袭击。这个问题的建议解决方案包括SYN cookie和cryptographic puzzles,尽管SYN cookie有它们自己的一组漏洞。[29] Sockstress是类似的攻击,可以通过系统资源管理来缓解。[30] Phrack #66中分析了一个高级DoS攻击,该攻击涉及对TCP持久定时器的利用。[31] 推送和确认洪水是其他变体。[32]
能够窃听一个TCP会话并重定向数据包的攻击者可以劫持一个TCP连接。为此,攻击者从正在进行的通信中学习序列号,并伪造一个看起来像流中下一个片段的假片段。这种简单的劫持会导致一个数据包在一端被错误地接受。当接收主机向连接的另一端确认额外的段时,同步就会丢失。劫持可能与地址解析协议(ARP)或路由攻击相结合,允许控制数据包流,从而获得对被劫持的TCP连接的永久控制。[33]
在1948年RFC之前,模拟不同的IP地址并不困难,当时的初始序列号很容易猜测。这使得攻击者能够不需要部署ARP或路由攻击就可以盲目发送接收者认为来自不同的IP地址的数据包序列,:这足以确保被模拟的IP地址主机的合法性,或者使用拒绝服务攻击将其置于这种状态。这就是初始序列号如今采用随机选择的原因。
能够窃听并预测下一个要发送的数据包大小的攻击者可能会导致接收方接收到恶意负载,而不会中断现有连接。攻击者使用下一个预期数据包的序列号和有效负载大小注入恶意数据包。当合法数据包最终被接收时,发现其序列号和长度与已经接收到的数据包相同,并且作为正常的重复数据包被无声地丢弃——合法数据包被恶意数据包“否决”。与连接劫持不同,连接永远不会失去同步,在恶意负载被接受后,通信会照常继续。TCP的否决将使攻击者对通信的控制更少,但使攻击特别难以被检测到。避免了确认风暴导致的网络流量的大幅增加。对接收者来说,唯一有问题的证据就是一个重复的数据包,这是在一个网络中的正常现象。被否决的数据包的发送者从未看到任何攻击的证据。[34]
另一个漏洞是TCP重置攻击。
TCP和UDP使用端口号来标识主机上的发送和接收应用程序端点,通常称为互联网套接字。TCP连接的每一侧都有一个由发送或接收应用程序保留的相关联的16位无符号端口号(0-65535)。到达的数据包通过其套接字(即源主机地址、源端口、目的主机地址和目的端口的组合)被识别为属于特定的TCP连接。这意味着服务器计算机可以同时向几个客户机提供不同的服务,只要客户机负责从不同的源端口发起到一个目的端口的任何同时连接。
端口号分为三个基本类别:众所周知的、注册的和动态/私有的。众所周知的端口由互联网分配号码管理局(IANA)分配,通常由系统级或根进程使用。作为服务器运行并被动侦听连接的众所周知的应用程序通常使用这些端口。一些例子包括:FTP (20和21)、SSH (22)、TELNET (23)、SMTP (25)、基于SSL/TLS的超文本传输协议(443)和超文本传输协议(80)。终端用户应用程序在联系服务器时通常使用注册端口作为短暂的源端口,但它们也可以识别已由第三方注册的命名服务。最终用户应用程序也可以使用动态/私有端口,但这种情况并不常见。动态/专用端口不包含任何特定TCP连接之外的任何定义。
网络地址转换(NAT)通常使用“面向互联网”公共端的动态端口号来消除公共网络和私有子网之间的通信流的歧义,从而允许子网中的许多IP地址(及其端口)由一个面向公共的地址提供服务。
TCP是一个复杂的协议。然而,尽管多年来已经做出并提出了重大改进,但自1974年第一个规范RFC 675和1981年9月发布的v4规范RFC 793以来,其最基本的操作并未发生显著变化。RFC 1122《互联网主机的主机要求》阐明了许多TCP协议实施要求。RFC 7414中提供了8个要求的规格和20多个被强烈推荐的增强功能列表。其中包括RFC 2581,近年来最重要的与传输控制协议相关的RFC之一的传输控制协议拥塞控制描述了避免过度拥塞的更新算法。2001年,RFC 3168被用来描述显式拥塞通知(ECN),一种拥塞避免信令机制。
最初的TCP拥塞避免算法被称为“TCP Tahoe”,但后来提出了许多替代算法(包括TCP Reno、TCP Vegas、FAST TCP、TCP New Reno和TCP Hybla)。
网络传输协议交互(iTCP) [35] 是对网络传输协议扩展的一项研究工作,它允许应用程序订阅网络传输协议事件并注册处理程序组件,这些组件可以为各种目的启动应用程序,包括应用程序辅助的拥塞控制。
多路径传输控制协议(MPTCP) [36][37] 是IETF内部正在进行的一项工作,旨在允许一个传输控制协议连接使用多条路径来最大限度地利用资源和增加冗余。无线网络环境中多路径传输控制协议提供的冗余支持同时利用不同的网络,从而带来更高的吞吐量和更好的切换能力。多路径传输控制协议也给数据中心环境带来了性能优势。[38] [39] 多路径传输控制协议的参考实现正在Linux内核中开发。[40] 多路径传输控制协议用于支持iphone、ipad和MAC上的语音识别应用Siri。 [41]
TCP Cookie Transactions (TCPCT)是2009年12月提出的一个扩展,旨在保护服务器免受拒绝服务攻击。与SYN cookies不同,TCPCT不与窗口缩放等其他TCP扩展冲突。TCPCT是由于DNSSEC的需要而设计的,那里的服务器必须处理大量的短时间的传输控制协议连接。
tcpcrypt是2010年7月提出的扩展程序,直接在TCP本身中提供传输层加密。它不需要任何配置就可以被设计成透明的工作模式。与TLS (SSL)不同,tcpcrypt本身不提供身份验证,但是它提供简单应用程序原语。截至2010年,第一份tcpcrypt IETF草案已经发布,并已在几个主要平台上实施。
TCP快速打开是加速两个端点之间的连续TCP连接打开的扩展。它通过使用加密“cookie”跳过三次握手来工作。它类似于早期的一个被称为传输控制协议(T/TCP)的提案,该提案由于安全问题而没有被广泛采用。[42] TCP FAST OPEN于2014年作为RFC 7413发布。[43]
2013年5月提出的比例减速比(PRR)是谷歌工程师开发的一个TCP扩展。PRR确保恢复后的TCP窗口大小尽可能接近慢速启动阈值。[44] 该算法旨在提高恢复速度,是Linux 3.2+内核中默认的拥塞控制算法。[45]
TCP最初是为有线网络设计的。数据包丢失被认为是网络拥塞的结果,作为预防措施,拥塞窗口的大小会显著减小。然而,众所周知,由于衰落、阴影、切换、干扰和其他无线电效应,无线链路会经历零星的且通常是暂时的损耗,这些并非严格意义上的拥塞。由于无线分组丢失,在拥塞窗口大小(错误)逐渐减少之后,可能会有拥塞避免阶段,窗口大小会保守地减小。这导致无线电链路未得到充分利用。已经对消除这些有害影响进行了广泛的研究。建议的解决方案可分为端到端解决方案(需要在客户端或服务器端进行修改),[46] 链路层解决方案(如蜂窝网络中的无线链路协议(RLP))或基于代理的解决方案(需要在不修改端节点的情况下对网络进行一些更改)。[46][47]
许多替代拥塞控制算法,如维加斯、韦斯特伍德、韦诺和圣克鲁斯(Vegas, Westwood, Veno, and Santa Cruz),已经被提出来帮助解决无线问题。
克服传输控制协议处理能力要求的一种方法是构建它的硬件实现,众所周知的是传输控制协议卸载引擎(TOE)。TOEs的主要问题是它们很难集成到计算系统中,需要对计算机或设备的操作系统进行广泛的更改。Alacritech就是开发这种设备的一家公司。
数据包嗅探器(又称协议分析仪)可拦截网络链路上的传输控制协议流量,通过向用户显示哪些数据包正在通过链路,在调试使用传输控制协议的网络、网络堆栈和应用程序时非常有用。一些网络堆栈支持SO_DEBUG套接字选项,可以使用setsockopt在套接字上启用该选项。该选项转储该套接字上的所有数据包、TCP状态和事件,这有助于调试。Netstat是另一个可用于调试的实用程序。
对于许多应用来说,TCP是不合适的。一个问题(至少在正常实现中)是,在接收到丢失分组的重传副本之前,应用程序不能访问丢失分组之后的分组。这给流媒体、实时多人游戏和网络电话等实时应用带来了问题,在这些应用中,及时获取大部分数据通常比有序获取所有数据更有用。
出于历史和性能原因,大多数存储区域网络通过光纤通道连接并使用光纤通道协议(FCP)。
此外,对于嵌入式系统、网络引导和服务于来自大量客户端的简单请求的服务器(例如,DNS服务器),TCP的复杂性可能是个问题。最后,一些技巧,例如在两台主机之间传输数据,这两台主机都在网络地址转换(使用STUN或类似的系统)之后,如果没有像TCP这样相对复杂的协议,数据传输会变得很简单。
一般来说,在不适合传输控制协议的地方,使用用户数据报协议(UDP)。这提供了应用程序多路复用和校验和,而TCP可以,但不处理流或重传,使应用程序开发人员能够以适合情况的方式对它们进行编码,或者用前向纠错或插值等其他方法来替换它们。
流控制传输协议(SCTP)是另一种提供类似于TCP的可靠的面向流的服务的协议。它比TCP更新、复杂得多,还没有得到广泛部署。但是,它特别设计用于可靠性和近实时性非常重要的情况。
文丘里传输协议(VTP)是一项专利专有协议,旨在取代TCP,以克服低效率的无线数据传输。
TCP在高带宽环境中也有问题。对于事先不知道数据发送者的特殊环境,TCP拥塞避免算法工作得非常好。如果环境是可预测的,基于定时的协议,如异步传输模式,可以避免传输控制协议的重传开销。
在具有高带宽延迟产品的网络中,基于UDP的数据传输协议(UDT)比TCP具有更好的效率和公平性。[48]
多用途事务协议(MTP/IP)是专利专有软件,是一款设计用于在各种网络条件下自适应地实现高吞吐量和高传输性能的软件,尤其是在那些认为TCP效率低下的网络条件下。
当TCP在IPv4上运行时,用于计算校验和的方法在RFC 793中定义:
校验和字段是报头和文本中所有16位字的补码总和的16位补码。如果一个段包含奇数个要校验和的报头和文本八位字节,最后一个八位字节在右边用零填充,以形成一个用于校验和目的的16位字。被填补的部分不作为段的一部分传输。在计算校验和时,校验和字段本身被零取代。
换句话说,在适当的填充之后,所有16位的字都用补码算法相加。然后对总和进行逐位补码,并将其作为校验和字段插入。下表显示了模拟校验和计算中使用的IPv4数据包报头的伪报头。
Bit offset | 0–3 | 4–7 | 8–15 | 16–31 | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Source address | |||||||||||||||||||||||||||||||
32 | Destination address | |||||||||||||||||||||||||||||||
64 | Zeros | Protocol | TCP length | |||||||||||||||||||||||||||||
96 | Source port | Destination port | ||||||||||||||||||||||||||||||
128 | Sequence number | |||||||||||||||||||||||||||||||
160 | Acknowledgement number | |||||||||||||||||||||||||||||||
192 | Data offset | Reserved | Flags | Window | ||||||||||||||||||||||||||||
224 | Checksum | Urgent pointer | ||||||||||||||||||||||||||||||
256 | Options (optional) | |||||||||||||||||||||||||||||||
256/288+ | Data |
源地址和目的地址是IPv4报头的地址。TCP的协议值为6。“传输控制协议长度”字段是传输控制协议报头和数据的长度(以八位字节为单位)。
当TCP在IPv6上运行时,计算校验和的方法会发生变化,如RFC 2460:
下面显示了一个模拟IPv6报头以计算校验和的伪报头。
Bit offset | 0–7 | 8–15 | 16–23 | 24–31 | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Source address | |||||||||||||||||||||||||||||||
32 | ||||||||||||||||||||||||||||||||
64 | ||||||||||||||||||||||||||||||||
96 | ||||||||||||||||||||||||||||||||
128 | Destination address | |||||||||||||||||||||||||||||||
160 | ||||||||||||||||||||||||||||||||
192 | ||||||||||||||||||||||||||||||||
224 | ||||||||||||||||||||||||||||||||
256 | TCP length | |||||||||||||||||||||||||||||||
288 | Zeros | Next header | ||||||||||||||||||||||||||||||
320 | Source port | Destination port | ||||||||||||||||||||||||||||||
352 | Sequence number | |||||||||||||||||||||||||||||||
384 | Acknowledgement number | |||||||||||||||||||||||||||||||
416 | Data offset | Reserved | Flags | Window | ||||||||||||||||||||||||||||
448 | Checksum | Urgent pointer | ||||||||||||||||||||||||||||||
480 | Options (optional) | |||||||||||||||||||||||||||||||
480/512+ | Data |
许多TCP/IP软件堆栈实现提供了使用硬件辅助的选项,以便在传输到网络之前或从网络接收到校验和进行验证时,自动计算网络适配器中的校验和。这可能会减轻操作系统使用宝贵的CPU周期计算校验和的负担。因此,整体网络性能得以提高。
此功能可能会导致不知道或不确定校验和卸载其使用的尚未达到网络适配器的出站数据包中的无效校验和。[49] 这只会发生在网络适配器传输之前被截获的数据包上;网络适配器在网络线路上传输的所有数据包都将具有有效的校验和。[50] 当监控同一主机上虚拟机之间传输的数据包时,也会出现此问题,因为虚拟设备驱动程序知道校验和将由虚拟机主机内核或其物理硬件计算,因此可能会忽略校验和计算(作为优化)。
^Vinton G. Cerf; Robert E. Kahn (May 1974). "A Protocol for Packet Network Intercommunication". IEEE Transactions on Communications. 22 (5): 637–648. doi:10.1109/tcom.1974.1092259. Archived from the original|archive-url= requires |url= (help) on March 4, 2016..
^Bennett, Richard (September 2009). "Designed for Change: End-to-End Arguments, Internet Innovation, and the Net Neutrality Debate" (PDF). Information Technology and Innovation Foundation. p. 11. Retrieved 11 September 2017..
^Comer, Douglas E. (2006). Internetworking with TCP/IP: Principles, Protocols, and Architecture. 1 (5th ed.). Prentice Hall. ISBN 978-0-13-187671-2..
^"TCP (Linktionary term)"..
^"RFC 791 – section 2.1"..
^"RFC 793"..
^"RFC 1323, TCP Extensions for High Performance, Section 2.2"..
^"RFC 2018, TCP Selective Acknowledgement Options, Section 2"..
^"RFC 2018, TCP Selective Acknowledgement Options, Section 3"..
^"RFC 1323, TCP Extensions for High Performance, Section 3.2"..
^"Transmission Control Protocol (TCP) Parameters: TCP Option Kind Numbers". IANA..
^RFC 793 section 3.1.
^RFC 793 Section 3.2.
^Tanenbaum, Andrew S. (2003-03-17). Computer Networks (Fourth ed.). Prentice Hall. ISBN 978-0-13-066102-9..
^"TCP Definition". Retrieved 2011-03-12..
^Mathis; Mathew; Semke; Mahdavi; Ott (1997). "The macroscopic behavior of the TCP congestion avoidance algorithm". ACM SIGCOMM Computer Communication Review. 27 (3): 67–82. CiteSeerX 10.1.1.40.7002. doi:10.1145/263932.264023..
^Paxson, V.; Allman, M.; Chu, J.; Sargent, M.. The Basic Algorithm. Computing TCP's Retransmission Timer. IETF. June 2011: p. 2. sec. 2 [October 24, 2015]. RFC 6298..
^Stone; Partridge (2000). "When The CRC and TCP Checksum Disagree". ACM SIGCOMM Computer Communication Review: 309–319. CiteSeerX 10.1.1.27.7611. doi:10.1145/347059.347561. ISBN 978-1581132236..
^"RFC 879"..
^"TCP window scaling and broken routers [LWN.net]"..
^David Murray; Terry Koziniec; Sebastian Zander; Michael Dixon; Polychronis Koutsakis (2017). "An Analysis of Changing Enterprise Network Traffic Characteristics" (PDF). The 23rd Asia-Pacific Conference on Communications (APCC 2017). Retrieved 3 October 2017..
^"IP sysctl". Linux Kernel Documentation. Retrieved 15 December 2018..
^Wang, Eve. "TCP timestamp is disabled". Technet - Windows Server 2012 Essentials. Microsoft..
^Gont, Fernando (November 2008). "On the implementation of TCP urgent data". 73rd IETF meeting. Retrieved 2009-01-04..
^Peterson, Larry (2003). Computer Networks. Morgan Kaufmann. p. 401. ISBN 978-1-55860-832-0..
^Richard W. Stevens (November 2011). TCP/IP Illustrated. Vol. 1, The protocols. Addison-Wesley. pp. Chapter 20. ISBN 978-0-201-63346-7..
^"Security Assessment of the Transmission Control Protocol (TCP)" (PDF). Archived from the original on March 6, 2009. Retrieved 2010-12-23.CS1 maint: BOT: original-url status unknown (link).
^Security Assessment of the Transmission Control Protocol (TCP).
^Jakob Lell. "Quick Blind TCP Connection Spoofing with SYN Cookies". Retrieved 2014-02-05..
^"Some insights about the recent TCP DoS (Denial of Service) vulnerabilities" (PDF)..
^"Exploiting TCP and the Persist Timer Infiniteness"..
^"PUSH and ACK Flood". f5.com..
^"Laurent Joncheray, Simple Active Attack Against TCP, 1995"..
^John T. Hagen; Barry E. Mullins (2013). TCP veto: A novel network attack and its application to SCADA protocols. Innovative Smart Grid Technologies (ISGT), 2013 IEEE PES. pp. 1–6. doi:10.1109/ISGT.2013.6497785. ISBN 978-1-4673-4896-6..
^"TCP Interactive". www.medianet.kent.edu..
^RFC 6182.
^RFC 6824.
^Raiciu; Barre; Pluntke; Greenhalgh; Wischik; Handley (2011). "Improving datacenter performance and robustness with multipath TCP". ACM SIGCOMM Computer Communication Review. 41 (4): 266. CiteSeerX 10.1.1.306.3863. doi:10.1145/2043164.2018467..
^"MultiPath TCP - Linux Kernel implementation"..
^Raiciu; Paasch; Barre; Ford; Honda; Duchene; Bonaventure; Handley (2012). "How Hard Can It Be? Designing and Implementing a Deployable Multipath TCP". Usenix Nsdi: 399–412..
^Bonaventure; Seo (2016). "Multipath TCP Deployments". IETF Journal..
^Michael Kerrisk (2012-08-01). "TCP Fast Open: expediting web services". LWN.net..
^Yuchung Cheng; Jerry Chu; Sivasankar Radhakrishnan & Arvind Jain (December 2014). "TCP Fast Open". IETF. Retrieved 10 January 2015..
^"RFC 6937 - Proportional Rate Reduction for TCP". Retrieved 6 June 2014..
^Grigorik, Ilya (2013). High-performance browser networking (1. ed.). Beijing: O'Reilly. ISBN 978-1449344764..
^"TCP performance over CDMA2000 RLP". Archived from the original on 2011-05-03. Retrieved 2010-08-30.
^Muhammad Adeel & Ahmad Ali Iqbal (2004). TCP Congestion Window Optimization for CDMA2000 Packet Data Networks. International Conference on Information Technology (ITNG'07). pp. 31–35. doi:10.1109/ITNG.2007.190. ISBN 978-0-7695-2776-5..
^Yunhong Gu, Xinwei Hong, and Robert L. Grossman. "An Analysis of AIMD Algorithm with Decreasing Increases". 2004..
^"Wireshark: Offloading". Wireshark captures packets before they are sent to the network adapter. It won't see the correct checksum because it has not been calculated yet. Even worse, most OSes don't bother initialize this data so you're probably seeing little chunks of memory that you shouldn't. New installations of Wireshark 1.2 and above disable IP, TCP, and UDP checksum validation by default. You can disable checksum validation in each of those dissectors by hand if needed..
^"Wireshark: Checksums". Checksum offloading often causes confusion as the network packets to be transmitted are handed over to Wireshark before the checksums are actually calculated. Wireshark gets these “empty” checksums and displays them as invalid, even though the packets will contain valid checksums when they leave the network hardware later..
暂无