RFC6824 翻译 译文

TCP Extensions for Multipath Operati on with Multiple Addresses

RFC 6824

Abstract

TCP/IP通信目前限制在每个连接只有一条路径,但是在对等点之间经常存在多条路径。同时为TCP/IP会话使用这些多路径将改善网络中的资源使用,从而通过更高的吞吐量和对网络故障的恢复能力来改善用户体验。

 

多路径TCP提供了在对等点之间同时使用多条路径的能力。本文介绍了一组对传统TCP的扩展,以支持多路径操作。协议为应用程序提供与TCP(即TCP)相同类型的服务。它提供了必要的组件,以建立和使用多个TCP流跨潜在的不连接路径。

1 Introduction

多路径TCP (MPTCP)是对常规TCP[1]的一组扩展,用于提供多路径TCP[2]服务,该服务允许传输连接在多个路径上同时操作。本文介绍了为TCP添加多路径功能所需的协议更改;具体来说,那些用于发送信号和设置多个路径(“子流”)、管理这些子流、重新组装数据和终止会话的子路径。然而,这并不是创建多路径TCP实现所需要的唯一信息。本文件由另外三份文件补充:

  1. 体系结构[2]解释了多路径TCP背后的动机,它包含了对该设计所基于的高级设计决策的讨论,以及对功能分离的解释,通过这种分离可以开发可扩展的MPTCP实现。

[2]Ford, A., Raiciu, C., Handley, M., Barre, S., and J. Iyengar, "Architectural Guidelines for Multipath TCP Development", RFC 6182, March 2011.

  1. 拥塞控制[5]提出了一种安全的拥塞控制算法来耦合多个路径的行为,以“不伤害”其他网络用户。

[5] Raiciu, C., Handley, M., and D. Wischik, "Coupled Congestion Control for Multipath Transport Protocols", RFC 6356, October 2011.

  1. 应用程序注意事项[6]讨论了MPTCP对应用程序的影响、应用程序想要使用MPTCP做什么,以及由于这些因素,MPTCP实现应该提供哪些API扩展。

[6] Scharf, M. and A. Ford, "MPTCP Application Interface Considerations", Work in Progress, October 2012.

1.1 设计的假设

为了限制潜在的巨大设计空间,工作组对本文中提出的多路径TCP设计施加了两个关键约束:

  1. 它必须向后兼容当前的常规TCP,以增加部署的机会。
  2. 可以假设一个或两个主机是多宿主和多地址的。

 

为了简化设计,我们假设在主机上存在多个地址就足以表明存在多个路径。这些路径不必完全分离:它们之间可能共享一个或多个路由器。即使在这种情况下,使用多个路径也是有益的,可以提高资源利用率和对节点故障子集的恢复能力。[5]中定义的拥塞控制算法确保这不会造成损害。此外,在某些场景中,单个主机上的不同TCP端口可以提供分离路径(例如通过某些等成本的多路径(ECMP)实现[7]),因此MPTCP设计还支持在路径标识符中使用端口。

 

上面列出的向后兼容性有三个方面(详见[2]):

  1. 外部约束: 协议必须通过大多数现有的中间件(如NATs、防火墙和代理)来运行,因此必须尽可能在网络上类似于现有的TCP。此外,协议不能假定它在网络上发送的段未经过修改就到达目的地:它们可能被分离或合并;TCP选项可能被删除或重复。
  2. 应用程序约束: 该协议必须在不更改使用通用TCP API的现有应用程序的情况下可用(尽管并非所有特性都适用于此类遗留应用程序是合理的)。此外,协议必须为应用程序提供与常规TCP相同的服务模型。
  3. 回退: 协议应该能够在不受用户干扰的情况下退回到标准TCP,以便能够与遗留主机通信。

1.2 MPTCP在网络协议栈中

MPTCP操作在传输层,目标是对更高和更低的层都透明。它是标准TCP之上的一组附加特性; 图1说明了这种分层。MPTCP被设计成可由遗留应用程序使用,而无需更改; 在[6]中详细讨论了它与应用程序的交互。

 

1.3 术语

  1. 路径(path): 发送方和接收方之间的链接序列,在此上下文中由4元组源地址和目标地址/端口对 定义。
  2. 子流(subflow): 在单个路径上操作的TCP流,它构成一个更大的MPTCP连接的一部分。子流的启动和终止类似于常规TCP连接。
  3. 连接(MPTCP Connection): 一个或多个子流的集合,应用程序可以通过它在两个主机之间进行通信。连接和应用程序套接字之间有一对一的映射。
  4. 数据平面(Data-Level): 有效负载数据名义上通过连接传输,而连接又通过子流传输。因此,术语“data-level”与“connection-level”同义,而“subflow-level”指的是单个子流的属性。
  5. 令牌(Token): 由主机提供给多路径连接的本地唯一标识符。也可以称为“连接ID”
  6. 主机(Host): 操作MPTCP实现并初始化或接受MPTCP连接的最终主机。

1.4 MPTCP概念

本节提供MPTCP正常操作的高级摘要,Figure 2所示的场景对此进行了说明。第3节详细描述了操作。

 

  1. 对于不支持MPTCP的应用程序,MPTCP的行为与普通TCP相同。扩展api可以为支持mptcp的应用程序[6]提供额外的控制。应用程序以正常方式打开TCP套接字开始。MPTCP信号和操作由MPTCP实现处理。
  2. MPTCP连接的开始类似于常规TCP连接。如图2所示,分别在主机A和B上的地址A1和B1之间建立了MPTCP连接。
  3. 如果有额外的路径可用,就会在这些路径上创建额外的TCP会话(称为MPTCP“子流”),并与现有的会话结合起来,而现有会话仍然是两端应用程序的单个连接。在主机A上的地址A2和主机B上的地址B1之间演示了额外TCP会话的创建。
  4. MPTCP通过在主机上存在多个地址来标识多个路径。这些多个地址的组合等于附加的路径。在本例中,可以设置的其他潜在路径有A1<->B2和A2<->B2。虽然这一额外的会话显示是由A2发起的,但它也可能是由B1发起的。
  5. 通过路径管理方法发现和设置附加子流; 本文档描述了一种机制,通过这种机制,主机可以通过使用自己的附加地址或向其他主机发送可用地址来发起新的子流。
  6. MPTCP添加了连接级序列号,允许以不同的网络延迟重新组装到达多个子流的报文段。
  7. 子流以常规TCP连接的方式终止,用四次FIN握手。MPTCP连接被连接级FIN终止。

2 操作概览

本节介绍关于通用MPTCP操作的单个描述,涉及到协议操作。这是一个高级概述的关键功能;完整的规范如下第3节所述。这里不讨论可扩展性和协商特性。在本节中,大量引用了MPTCP选项的符号名——这些是IANA分配的MPTCP选项的子类型(参见第8节),它们的格式在第3节后面的详细协议规范中定义。

 

多路径TCP连接在两个主机之间提供双向的字节流,就像普通的TCP通信一样,因此不需要对应用程序进行任何更改。但是,多路径TCP允许主机使用具有不同IP地址的不同路径来交换属于MPTCP连接的包多路径TCP连接看起来像应用程序的普通TCP连接。然而,对于网络层来说,每个MPTCP子流看起来都像一个常规的TCP流,其段携带新的TCP选项类型。多路径TCP管理这些子流的创建、删除和使用,以发送数据。在多路径TCP连接中管理的子流的数量不是固定的,它可以在多路径TCP连接的生命周期内波动。

 

所有MPTCP操作都用一个TCP选项发出信号——MPTCP的单个数字类型,每个MPTCP消息都有“子类型”。以下是这些信息的目的和原理的摘要。

2.1 初始化一个MPTCP连接

这与初始化普通TCP连接的信号相同,但是SYN、SYN/ACK和ACK包也带有MP_CAPABLE选项。这是可变长度,有多种用途。首先,验证远程主机是否支持多路径TCP;其次,这个选项允许主机交换一些信息来验证附加子流的建立。更多细节见3.1节。

 

2.2 将新的子流与现有的MPTCP连接关联起来

在MP_CAPABLE握手中交换key提供了在设置新子流时用于鉴定端点的材料。其他子流的启动方式与初始化普通TCP连接相同,但是SYN、SYN/ACK和ACK包也带有MP_JOIN选项。

主机A在它的一个地址和主机B的一个地址之间启动一个新的子流。从密钥生成的令牌用于标识它要连接的MPTCP连接HMAC用于身份验证。基于哈希的消息身份验证代码(HMAC)使用在MP_CAPABLE握手中交换的密钥,以及在这些MP_JOIN选项中交换的随机数(nonces)。MP_JOIN还包含标志和地址ID,可以用来引用源地址,而发送方不需要知道它是否被NAT更改了。

 

2.3 通知另一个主机另一个潜在的地址

与多宿主主机关联的IP地址集可能在MPTCP连接的生命周期内发生更改。MPTCP支持隐式和显式地在主机上添加和删除地址。如果主机A已经建立了一个从地址IP#-A1开始的子流,并且想要打开第二个从地址IP#-A2开始的子流,那么它就会像前面解释的那样启动子流的建立。然后,远程主机将被隐式告知新地址。

 

在某些情况下,主机可能希望向远程主机公告地址的可用性,而不需要建立新的子流,例如,当NAT阻止在一个方向设置时。在下面的示例中,主机A告知主机B它的替代IP地址(IP#-A2)。主机B稍后可能会将MP_JOIN发送到这个新地址。由于存在可以转换IP地址的中间件,因此此选项使用地址标识符明确地标识主机上的地址。更多细节见3.4.1节。

 

有一个对应的地址删除信号,利用地址ID在添加地址握手时发出信号。更多细节见3.4.2节。

 

2.4 使用MPTCP进行数据传输

为了确保可靠、有序地在可能随时出现和消失的子流上交付数据,MPTCP使用64数据序列号(DSN)对通过MPTCP连接发送的所有数据进行编号。每个子流都有自己的32位序列号空间,MPTCP选项将子流序列空间映射到数据序列空间。这样,在发生故障时,可以在不同的子流(映射到相同的DSN)上重新传输数据。

 

“数据序列信号("Data Sequence Signal")”携带“数据序列映射("Data Sequence Mapping")”。数据序列映射由子流序号、数据序号和该映射有效的长度(subflow sequence number, data

sequence number, and length)组成。此选项还可以为接收到的DSN携带连接级别确认(“数据ACK”)。

 

使用MPTCP,所有子流共享相同的接收缓冲区,并公告相同的接收窗口。在MPTCP中有两个级别的确认。在每个子流上使用常规的TCP确认,以确认通过子流发送的段的接收独立于它们的DSN。此外,还有对数据序列空间的连接级确认。这些确认跟踪字节流和滑动接收窗口。

 

2.5 请求更改路径的优先级

在初始子流设置时,主机可以指示是否希望将子流用作常规路径或备份路径——只有在没有常规路径可用时才使用备份路径。在连接期间,主机a可以通过MP_PRIO信号向主机b请求子流优先级的更改。

 

2.6 关闭一个MPTCP连接

当主机A想通知主机B它没有更多的数据要发送时,它将这个“数据FIN” 信号作为数据序列信号的一部分(见上文)。它具有与常规TCP FIN相同的语义和行为,但在连接级别。一旦成功接收到MPTCP连接上的所有数据,就会在连接级别使用DATA_ACK确认此消息。更多细节见3.3.3节。

 

2.7 显著的特征

值得强调的是,MPTCP的信号设计考虑了以下几个关键需求:

  1. 为了处理路径上的NAT,地址是通过地址ID来引用的,以防IP包的源地址被NAT改变。为了允许在NAT后面的任何一端都创建子流,MPTCP使用ADD_ADDR消息。
  2. 如果MPTCP操作不可能,例如,如果一台主机不支持MPTCP,或者如果一个中间件改变了负载,MPTCP就会回到普通TCP。
  3. 为了应对[9]中识别的威胁,我们采取了以下步骤:在MP_CAPABLE消息中以明文发送密钥; MP_JOIN消息使用HMAC-SHA1([10],[4])使用这些keys进行保护; 对其他消息进行标准TCP有效性检查(确保序列号在窗口内)。

3 MPTCP协议

 

所有MPTCP操作都使用可选的TCP报头字段发出信号。IANA为MPTCP分配了单个TCP选项号(“种类”),然后由一个“子类型”确定单个消息,子类型的值也存储在IANA注册中心(并在第8部分中列出)。

 

在整个文档中,当通过符号名(如“MP_CAPABLE”)引用MPTCP选项时,这指的是带有单个MPTCP选项类型的TCP选项,以及第8节中定义的符号名的子类型值。这个子类型是一个4位字段——选项有效负载的前4位,如图3所示。MPTCP消息在以下部分中定义。

 

那些与子流初始化相关的MPTCP选项用于设置SYN标志的包。此外,还有一个MPTCP选项用于向元数据发送信号,以确保分段数据可以重新组合,以便交付给应用程序。

 

然而,剩下的选项是不需要在特定数据包上的信号,例如用于发送额外地址的信号。虽然一个实现可能希望尽快发送MPTCP选项,但是不可能将所有希望的选项(MPTCP和常规TCP的选项,比如SACK(选择性应答)[11])合并到一个数据包中。因此,实现可以选择发送包含附加信令信息的重复ACK。这改变了重复ACK的语义;这些通常只作为在常规TCP中丢失的段[12]的信号发送。因此,接收包含MPTCP选项的重复ACK的MPTCP实现不能将其视为拥塞信号。此外,为了只发送MPTCP选项,MPTCP实现不应该在一行中发送两个以上的重复ack,以确保中间件不会将此误解为拥塞的信号。

 

此外,在处理任何MPTCP信号之前,必须进行标准TCP有效性检查(如确保序列号和确认号在窗口内),如[13]所述。

3.1 连接初始化

连接启动从单路径上的SYN、SYN/ACK、ACK交换开始。每个包都包含Multipath Capable (MP_CAPABLE) TCP选项(图4)。此选项声明其发送方能够执行多路径TCP,并希望在此特定连接上执行。

 

 

此选项用于声明发送方为此MPTCP连接生成的64位密钥。此key用于验证向此连接添加的后续子流。这是唯一 一次把钥匙在电线上清楚地送进来(除非使用“快速关闭”,第3.5节);所有未来的子流都将使用32位的“令牌”来标识连接。这个令牌是这个密钥的哈希加密。此过程的算法取决于所选择的认证算法;选择的方法在本节后面定义。

 

此key由发送方生成,其生成方法是特定于实现的。密钥必须难以猜测,而且它必须是唯一的,在任何时候发送主机。在[14]中给出了生成用于key的随机数的建议。连接将通过令牌(密钥的单向散列)在每个主机上建立索引。因此,实现将需要从每个令牌映射到相应的连接,并依次映射到连接的键。

 

两个不同的key可能会散列到同一个令牌。散列冲突的风险通常很小,除非主机正在处理成千上万个连接。因此,在将key发送到SYN/ACK之前,实现应该检查它的连接令牌列表,以确保不会发生冲突。然而,对于具有数千个连接的服务器来说,这将是昂贵的。子流握手机制(第3.2节)将确保新的子流只通过加密握手连接正确的连接,以及在两个方向检查连接令牌,并确保序列号在窗口中。因此,在最坏的情况下,如果出现令牌冲突,新的子流将不会成功,但是MPTCP连接将继续提供常规的TCP服务

 

MP_CAPABLE选项在SYN、SYN/ACK和ACK包上执行,这些包启动MPTCP连接的第一个子流。每个数据包携带的数据如下: A =Initiator;B =Listener。

  1. SYN (A->B): A的key,对于这个连接。
  2. SYN/ACK (B->A): B的key,对于这个连接。
  3. ACK (A->B): A的key后面紧跟B的key。

 

选项的内容由包的SYN和ACK标志决定,由选项的length字段验证。对于图4所示的关系图,“sender”和“receiver”表示TCP包的sender或receiver (TCP包可以是任意主机)。如果设置了SYN标志,则包含一个key; 如果只设置了ACK标志,则两个key都存在。

 

ACK中重复显示了B的key,以允许侦听器(主机B)无状态地工作,直到TCP连接到达已建立的状态。但是,如果侦听器以这种方式进行操作,那么它必须以一种允许它在ACK中回显时验证它是否生成了key的方式生成它的key。

 

这种交换允许确定SYN包上MPTCP选项的安全通过。如果放弃了这些选项中的任何一个,MPTCP将优雅地退回到常规的单路径TCP,如3.6节所述。注意,在通过路径成功接收到数字签名标准(DSS)选项之前,不能建立新的子流(使用3.2节中记录的过程)。

 

 

MP_CAPABLE选项中的前4位(Figure 4)定义了MPTCP选项子类型(参见第8节;对于MP_CAPABLE,这是0),这个8位字节的其余4位指定正在使用的MPTCP版本(对于这个规范,这是0)。

 

第二个八位为标志保留,分配如下:

A最左边的位,标记为A”,应该设置为1,以指示“Checksum Required,除非系统管理员决定不需要Checksum(例如,如果环境受到控制,且不存在可能调整有效负载的中间件)。

B第二个位,标记为“B”,是一个可扩展标志,对于当前实现,必须设置为0。这将在以后的规范中用于可扩展性机制,此标志的影响将在以后的日子中定义。如果接收到的消息将B标志设置为1,且不理解这一点,则必须忽略此SYN; 发件人希望以与此遗留规范兼容的格式重试。注意,MP_CAPABLE选项的长度以及从“H”到“C”的位的含义可以通过设置B=1来更改。

C到H其余的位,从“C”到“H”,用于密码算法协商。目前只分配最右边的位,标记为“H”。位“H”表示使用HMAC-SHA1(如3.2节所定义)。仅支持此方法的实现必须将位“H”设为1,位“C”至“G”设为0。

 

必须指定密码算法。如果标记位C到H都是0,那么MP_CAPABLE选项必须被视为无效并被忽略(也就是说,它必须被视为常规的TCP握手)。

 

身份验证算法的选择也会影响生成令牌和初始数据序列号(IDSN)的算法。在这个规范中,只指定和选择SHA-1算法(位“H”),令牌必须是密钥的一个截断的(最重要的32位)SHA-1哈希([4],[15])。密钥的SHA-1散列的另一个64位截断(最不重要的64位)必须用作初始数据序列号。注意,密钥必须按网络字节顺序散列。还要注意,“最不重要的”位必须是SHA-1摘要中最右边的位,就像[4]中的那样。未来使用加密位的规范可以选择为令牌和IDSN生成指定不同的算法。

 

加密和校验位都以类似的方式协商功能。对于所需的校验和位(标记为“A”),如果任一主机需要使用校验和,则必须使用校验和。换句话说,不使用校验和的唯一方法是,如果两个主机的SYNs中都设置了A=0。通过设置握手的第三个包(ACK)中的“A”位,可以确认这个决定。

例如,如果发起者在SYN中设置了A=0,而响应者在SYN/ACK中设置了A=1,则必须在两个方向都使用校验和,并且发起者将在ACK中设置A=1。是否使用校验和的决定将由实现存储在每个连接的二进制状态变量中

 

对于密码协商,应答者可以选择。发起者为它支持的每个算法创建一个建议设置位(在这个规范的版本中,只有一个建议,所以位“H”总是设置为1)。这种行为的基本原理是,响应者通常是具有数千个连接的服务器,因此它可能希望选择一种计算复杂度最小的算法,具体取决于负载。如果响应器不支持(或不希望支持)发起者的任何建议,它可以在没有MP_CAPABLE选项的情况下响应,从而迫使回退到常规TCP。

 

MP_CAPABLE选项仅用于连接的第一个子流中,以标识连接;以下所有子流都将使用“Join”选项(参见3.2节)连接现有连接。

 

如果一个SYN包含一个MP_CAPABLE选项,而SYN/ACK不包含,则假定被动的开启人不支持多路径;因此,MPTCP会话必须作为常规的单路径TCP进行操作如果SYN不包含MP_CAPABLE选项,则SYN/ACK必须不包含相应的选项如果第三个包(ACK)不包含MP_CAPABLE选项,则会话必须退回到正常的单路径TCP操作。这是为了保持与路径上删除部分或全部TCP选项的中间件的兼容性。请注意,在决定以常规TCP方式操作之前,实现可能会多次尝试发送MPTCP选项(请参阅第3.8节)。

可以这样理解:

If SYN contains MP_CAPABLE:

If SYN/ACK contains MP_CAPABLE:

If ACK contains MP_CAPABLE:

Then use MPTCP;

 

如果SYN包未被确认,则由本地策略决定如何响应。预计发送方最终将退回到单路径TCP(即,没有MP_CAPABLE选项)用于处理可能丢弃带有未知选项的数据包的中间件; 然而,首先进行的多路径尝试的数量将取决于本地策略。MPTCP和非MPTCP SYNs可能在网络中被重新排序。因此,从TCP握手的第三个包中MP_CAPABLE选项的存在或不存在可以推断出最终状态。如果此选项不存在,则连接应退回到常规TCP,如3.6节所述。

 

MPTCP连接上的初始数据序列号是从密钥生成的。通过协商验证算法确定了IDSN生成算法。在本规范中,只指定和选择SHA-1算法,主机的IDSN必须是其密钥的SHA-1哈希的最不显著的64位,即, IDSN-A = Hash(Key-A)和IDSN-B = Hash(Key-B)。IDSN的这种确定性生成允许接收器在连接开始时确保序列空间中没有间隔。具有MP_CAPABLE的SYN占用数据序列空间的第一个八位元,尽管在发送第一个数据之前,不需要在连接级别承认这一点(请参阅3.3节)。

3.2 启动一个新的子流(subflow)

一旦MPTCP连接开始使用MP_CAPABLE交换,就可以向连接添加进一步的子流。主机知道自己的地址(es),并且可以通过3.4节中描述的信令交换知道其他主机的地址。使用此知识,主机可以在当前未使用的地址对上启动新的子流连接中的任意主机都可以开始创建新的子流,但是通常这将是原始连接发起者(有关启发式方法,请参阅第3.8节)。

 

一个新的子流作为一个普通的TCP SYN/ACK交换启动。连接(MP_JOIN) TCP选项用于标识要由新子流连接的连接。它使用在最初的MP_CAPABLE握手中交换的keying material (第3.1节),握手还协商了MP_JOIN握手中使用的加密算法。

 

本节使用HMAC-SHA1算法指定MP_JOIN的行为。MP_JOIN选项出现在三种握手方式的SYN、SYN/ACK和ACK中,尽管每种握手方式都有不同的格式。

 

在SYN包上的第一个MP_JOIN(Figure 5)中,发起者发送一个令牌、随机数和地址ID。

令牌用于标识MPTCP连接,是接收方密钥的加密散列,如在初始MP_CAPABLE握手中交换的那样(第3.1节)。在这个规范中,这个选项中的令牌由SHA-1([4],[15])算法生成,该算法被截断到最显著的32位。MP_JOIN选项中包含的令牌是包的接收者用来标识该连接的令牌。例如,主机A将发送令牌B(由key B生成)。注意,散列生成算法可以通过选择加密握手算法来重写,如3.1节所定义的那样。

 

MP_JOIN SYN不仅发送令牌(对于连接来说是静态的),还发送随机数(nonces),这些随机数用于防止对身份验证方法的重放攻击。为此目的生成随机数的建议见[14]。

 

MP_JOIN选项包含一个“地址ID”。这是一个只有在单个连接中才有意义的标识符,在这个连接中,它标识这个包的源地址,即使IP头在传输过程中被中间件箱更改了。地址ID允许地址删除(3.4.2节),而不需要知道接收者的源地址是什么,因此允许通过NATs删除地址。地址ID还允许新的子流设置尝试和地址信令之间的关联(第3.4.1节),以防止在同一路径上设置重复的子流,如果MP_JOIN和ADD_ADDR同时发送。

 

连接中第一个子流的初始SYN交换中使用的子流的地址ID是隐式的,值为零。主机必须为自己和远程主机存储地址ID和地址之间的映射。实现还需要知道哪些本地和远程地址ID与已建立的子流相关联,以便从本地或远程主机删除地址。

 

带有SYN标志的信息包上的MP_JOIN选项还包括4位标志,其中3位是当前保留的,发件人必须将其设置为零。最后一个位标记为“B”,表示此选项的发送方是否希望在其他路径失败时将此子流用作备份路径(B=1),或者是否希望立即将其用作连接的一部分。通过设置B=1,选项的发送方请求另一个主机仅在B=0时没有可用子流的情况下发送此子流上的数据。子流策略将在3.3.8节中详细讨论。

 

 

当接收到带有MP_JOIN选项的SYN时(该选项包含现有MPTCP连接的有效令牌),接收方应使用SYN/ACK进行响应,该SYN/ACK还包含MP_JOIN选项,其中包含一个随机数和一个截断的(最左64位)基于散列的消息身份验证代码(HMAC)。该选项的这个版本如Figure 6所示。如果令牌是未知的,或者主机想要拒绝子流建立(例如,由于它允许的子流数量的限制),接收器将发送一个重置(RST)信号,类似于TCP中的一个未知端口。虽然计算HMAC需要加密操作,但是MP_JOIN SYN中的32位令牌可以提供足够的保护,以防止盲目的状态耗尽攻击; 因此,不需要提供允许响应器在MP_JOIN阶段无状态地操作的机制。

 

HMAC由两台主机——第三个包(ACK)中的发起者(主机A)和第二个包(SYN/ACK)中的应答者(主机B)发送。在此阶段进行HMAC交换允许两个主机首先交换作为“消息”的随机数据(在前两个SYN包中)。该规范定义了使用[10]中定义的HMAC,以及SHA-1哈希算法[4](可能实现为[15]),从而生成一个160位/ 20- 8位的HMAC。由于选项空间限制,SYN/ACK中包含的HMAC被截断到最左边的64位,但这是可以接受的,因为使用了随机数;因此,攻击者只有一次机会正确猜测HMAC(如果HMAC不正确,则关闭TCP连接,因此需要使用新的随机数进行新的MP_JOIN协商)。

 

 

发起者的身份验证信息以其第一个ACK(第三种握手)发送,如Figure 7所示。该数据需要可靠地发送,因为这是唯一一次发送HMAC;因此,收到这个包必须触发一个常规的TCP ACK,如果不收到这个ACK,则必须重新传输数据包。换句话说,发送ACK / MP_JOIN包将子流放在pre_status中,它只在收到接收者的ACK时移动到已经确定的状态。在pre_status中不允许发送数据。在此选项中保留的部分必须由发送方设置为零。

 

 

对于主机A传输的消息,HMAC算法的键是key -A,后面跟着key -B; 对于主机B,后面跟着key -A。这些是在最初的MP_CAPABLE握手中交换的key。每种情况下HMAC算法的“消息”是每个主机(用R表示)的随机数的串联:对于主机A, R-A,后跟R-B;对于宿主B, R-B后面是R-A。

这些不同的TCP选项组合在一起以启用经过身份验证的子流设置,如图8所示。

 

  1. 如果主机B接收到的令牌未知,或者本地策略禁止接受新子流,则接收方必须为该子流响应TCP RST。
  2. 如果令牌在主机B上被接受,但是返回主机A的HMAC与预期的不匹配,主机A必须使用TCP RST关闭子流。
  3. 如果主机B没有收到预期的HMAC,或者ACK中缺少MP_JOIN选项,它必须使用TCP RST关闭子流。
  4. 如果HMACs被验证为正确的,那么两个主机已经相互验证为连接开始时存在的相同的对等点,并且他们已经同意这个子流将成为连接的一部分。
  5. 如果主机A接收到的SYN/ACK没有MP_JOIN选项,主机A必须使用RST关闭子流。

 

这涵盖了MP_JOIN丢失的所有情况。更详细地说,如果从路径上的SYN中去掉MP_JOIN,而主机B在相关端口上没有被动的启动器,那么它将以正常的方式响应RST。如果在回应一个SYN MP_JOIN选项,收到SYN / ACK没有MP_JOIN选项(因为它被剥夺了在返回路径,或被剥夺了在即将离任的路径但被动主机B回应,就好像它是一个新的常规TCP会话),然后子流不可用并且主机A必须以RST关闭它。

 

注意,可以在任意一对端口之间创建额外的子流(但启发式请参阅第3.8节);不需要显式的应用程序级别接受调用或绑定调用来打开其他子流。为了将新子流与现有连接相关联,在子流的SYN交换中提供的令牌用于解复用。然后将TCP子流的5元组绑定到连接的本地令牌。结果是允许任何端口对用于连接是可能的。

 

必须使用令牌进行反复用子流SYNs;这与传统的TCP不同,传统的TCP目的端口是用于解复用SYN包。一旦建立了子流,就像在传统的TCP协议中一样,使用5元组来解复用数据包。5元组将映射到本地连接标识符(令牌)。注意,主机A将知道子流的本地令牌,即使它不是在网络上发送的——只发送responder的令牌。

3.3 一般的MPTCP操作

本节讨论MPTCP用于数据传输的操作。在高层次上,MPTCP实现将从应用程序获取一个输入数据流,并将其拆分为一个或多个子流,并提供足够的控制信息,以便将其重新组装并可靠地交付给接收应用程序。下面的小节将详细定义此行为。

 

数据序列映射和数据应答信号的数据序列信号(DSS)选项(Figure 9)。有一方或者双方都可以表示在一个DSS,依赖于flag。数据序列映射定义了空间序列流映射到连接级别,和ACK确认收到数据连接级别。下面两个小节将更详细地描述这些函数。数据序列映射和数据ACK都可以在DSS选项中发出信号,这取决于设置的标志。

 

设置标志时,将定义此选项的内容,如下所示:

  1. A = Data ACK出现
  2. a = Data ACK是8个字节(如果没有设置,则是4个字节位)
  3. M = 数据序号(DSN)、子流序号(SSN)、数据级长度、校验和出现
  4. m = 数据序号为8个字节(如果没有设置,DSN为4个字节)

 

标记a和m只有在设置相应的A或M标志时才有意义;否则,它们将被忽略。此选项的最大长度(设置了所有标志)为28个字节。

 

F标志表示“DATA_FIN”。如果存在,这意味着该映射覆盖来自发送方的最终数据。这是连接级别,相当于单路径TCP中的FIN标志。除非有DATA_FIN交换或超时,否则连接不会关闭。DATA_FIN的用途以及此标志、子流级FIN标志和数据序列映射之间的交互在3.3.3节中进行了描述。此规范的实现必须将其余保留位设置为零。

 

注意,如果在MP_CAPABLE握手过程中使用了MPTCP校验和,那么校验和就只出现在这个选项中(请参阅3.1节)。校验和的存在可以从选项的长度推断出来。如果存在校验和,但在MP_CAPABLE握手中没有协商使用校验和,则必须忽略校验和字段。如果在协商使用校验和时不存在,则接收方必须使用RST关闭子流,因为它被认为是坏的。

3.3.1 数据序列映射(Data Sequence Mapping)

整个数据流可以通过使用DSS选项(图9)的数据序列映射组件来重新组装,这些组件定义了从子流序号到数据序号的映射接收方使用它来确保向应用层有序交付。同时,子流级序号(TCP报头中的规则序号)具有仅适用于subflow的相关性。可以期望(但不是强制)在子流级别使用SACK[11]来提高效率。

 

数据序列映射指定了从子流序列空间到数据序列空间的映射。这表示为子流和数据级别的起始序列号,以及此映射有效的字节长度。之所以选择这个显式映射为一系列的数据而不是每个包的信号来协助兼容TCP / IP分割或合并的情况下进行单独的堆栈生成数据流(例如,通过使用TCP网络接口卡分割出售,或等造成性能提高代理)。它还允许一个映射覆盖许多包,这在批量传输的情况下可能很有用。

 

映射是固定的,即在处理映射之后,子流序号被绑定到数据序号。在声明该映射之后,发送方不得更改该映射;但是,为了重新传输的目的,不同的子流可以映射到相同的数据序列号(参见3.3.6节)。这还允许为了恢复或提高效率的目的,在多个子流上同时发送相同的数据,特别是在有损链接的情况下。尽管这种操作的详细规范超出了本文的范围,但是实现应该将在数据序列空间的子流上接收的第一个数据视为应该交付给应用程序的数据,而忽略该序列空间的任何后续数据。

 

数据序列号被指定为一个绝对值,而子流序列编号是相对的(SYN的子流相对流序号0)。这是允许造成改变最初的子消息流的序号,如防火墙,进行随机化。

 

如果在MP_CAPABLE交换中协商使用校验和,则数据序列映射还包含该映射所涵盖的数据的校验和。校验和用于检测有效负载是否通过不支持mptcp的中间件以任何方式进行了调整。如果这个校验和失败,它将触发子流的失败,或者像3.6节中描述的那样,回退到常规TCP,因为MPTCP不再可靠地知道接收器上的子流序列空间来构建数据序列映射。

 

使用的校验和算法是标准的TCP校验和[1],操作这个映射所覆盖的数据,以及如图10所示的伪标头。

 

 

注意,伪标头中使用的数据序列号总是64位的值,而与DSS选项本身使用的长度无关。标准的TCP校验和算法已经被选择,因为它无论如何都要为TCP子流计算,如果在添加伪标头之前先计算数据,那么只需要计算一次。此外,由于TCP校验和是可添加的,DSN_MAP的校验和可以通过简单地将每个组成TCP段的数据的校验和相加,以及为DSS伪报头添加校验和来构造。

 

注意,校验和依赖于包含连续数据的TCP子流;因此,TCP子流不能使用紧急指针来中断现有的映射。然而,进一步注意,如果在子流上接收到紧急数据,则应该将其映射到数据序列空间,并将其交付给应用程序,类似于常规TCP中的紧急数据。

 

为了避免可能的死锁场景,子流级别的处理应该与连接级别的处理分开进行。因此,即使从子流空间到data-level空间的映射不存在,数据也应该被附加到子流(如果是窗口内的)。但是,这些数据不能在数据级别(3.3.2节)得到确认,因为它的数据序号是未知的。实现可能会在短时间内保留这些未映射的数据,期望映射很快就会到达。这些未映射的数据不能算作连接级别接收窗口中的数据,因为这是相对于数据序列号的,所以如果接收器耗尽了存储这些数据的内存,就必须丢弃它。如果该子流级序列空间的映射没有到达数据接收窗口,则该子流应该被视为断开的、用RST关闭的,并且任何未映射的数据应该被静静地丢弃。

 

数据序列号总是64位的,并且必须在实现中这样维护。如果连接进展速度缓慢,所以保护包装序列号不是必需的,那么它是允许的,包括的低32位数据序列号的数据序列映射和/或数据ACK作为优化和实现可以为每个包独立做出这样的选择。

 

如果实现以足够高的速率传输,32位值可以封装在最大段生存期(MSL)[16]中,那么它必须发送完整的64位数据序列号。在这些值(可能不同)中使用的DSNs的长度是用DSS选项中的标志来声明的。实现必须接受32位的DSN,并通过每次将32位的数列换行时递增上面的32位来隐式地将其提升到64位的数量。必须执行完整性检查,以确保换行发生在预期的时间(例如,序列号从一个非常高的数字跳到一个非常低的数字),而不是由outof顺序包触发。

 

与标准TCP序列号一样,数据序列号不应该从零开始,而是以一个随机值开始,从而使盲目会话劫持变得更加困难。此规范要求将每个主机的初始数据序号(IDSN)设置为主机s键SHA-1哈希值的最小64位,如3.1节所述。

 

数据序列映射不需要包含在每个MPTCP包中,只要该包中的子流序列空间被接收器上已知的映射所覆盖。这可以用于在事先知道映射的情况下减少开销;一种情况是,当主机之间有一个子流时,另一种情况是,数据段被调度成比包大小的块还要大的块。

 

通过将连接其余部分的子流级数据映射到连接级数据,可以使用“无限”映射返回到常规TCP(参见3.6节)。这是通过将DSS选项的数据级长度字段设置为保留值0来实现的。在这种情况下,校验和也将设置为零。

3.3.2 数据ACK

为了提供完整的端到端弹性,MPTCP提供了一个connection-level确认,作为整个连接的累积ACK。这是DSS选项的“数据ACK”字段(图9),数据ACK类似于标准TCP累积ACK的行为——指示成功接收了多少数据(没有漏洞)。这与subflow-level ACK相比,subflow-level ACK类似于TCP SACK,因为在连接级别的数据流中可能仍然存在漏洞。数据ACK指定它希望接收的下一个数据序列号。

 

 

 

 

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值