QUIC 的多路径扩展草案

原文地址:草案-ietf-quic-multipath-04

QUIC 的多路径扩展

抽象

本文档指定了 QUIC 协议的多路径扩展,以 允许同时使用多个路径进行单个连接。

讨论会场

在作为 RFC 发布之前,应删除此注释。

对本文档的讨论在 QUIC工作组邮件列表(quic@ietf.org), 存档于 quic

可以在 GitHub - quicwg/multipath: In-progress version of draft-ietf-quic-multipath 上找到此草案的来源和问题跟踪器。

此备忘录的状态

本互联网草案的提交完全符合《公约》的规定。 BCP 78 和 BCP 79 的规定。

互联网草案是互联网工程任务的工作文件 力 (IETF)。请注意,其他组也可能分发工作 作为互联网草稿的文件。当前互联网草案的列表是 在 Active Internet-Drafts.

互联网草稿是有效期最长为六个月的草稿文件 并可能在任何时候被其他文档更新、替换或废弃 时间。使用互联网草案作为参考是不合适的 材料或引用它们,而不是作为“正在进行的工作”。

本次互联网征求意见稿将于 2023 年 9 月 14 日到期。

1. 引言

本文档指定了 QUIC 版本 1 [QUIC-TRANSPORT] 的扩展,以允许单个路径同时使用多个路径 连接。

该提案基于几个基本设计要点:

  • 尽可能多地重用 QUIC 版本 1 的机制。在 具体而言,此提案使用为 QUIC 指定的路径验证 版本 1,旨在尽可能多地重用 QUIC 的连接 迁移。
  • 使用与 QUIC 版本 1 相同的数据包标头格式,以避免 数据包被中间盒丢弃的风险(可能仅支持 QUIC 版本 1)
  • 拥塞控制必须是每条路径(遵循 [QUIC-TRANSPORT]) 这通常还需要对每条路径进行 RTT 测量
  • PMTU 发现应按路径执行
  • 使用此多路径扩展需要使用非零 两个方向的连接 ID。
  • 路径由源 IP 和目标 IP 的 4 元组确定 地址以及源端口和目标端口。因此,可以有 每个 4 元组最多有一个活动路径/连接 ID。
  • 如果 4 元组在不使用新连接 ID 的情况下发生更改(例如 由于 NAT 重新绑定),这被视为迁移事件。

[QUIC-TRANSPORT] 第 9 节中指定的路径管理实现了多个目标:它指导对等体切换发送直通 一个新的首选路径,它允许对等方释放资源 与旧路径关联。多路径需要对 该机制:

  • 允许在多个上同时传输非探测帧 路径。
  • 继续使用现有路径,即使非探测帧具有 在另一条路径上被接收。
  • 管理已删除已删除的路径。

因此,此扩展指定了对 [QUIC-TRANSPORT] 第 9 节中的路径管理,因此 需要使用新的传输在两个终结点之间进行协商 参数,如第 3 节中指定。

此扩展使用多个数据包号空间。 协商多路径时, 每个目标连接 ID 都链接到单独的数据包号空间。 使用多个数据包号空间可以直接使用 [QUIC-RECOVERY]中定义的损失恢复和拥塞控制机制。

本规格 要求发送方在打开 其他路径。 QUIC 的某些部署使用零长度连接 ID。 但是,当节点选择使用零长度连接 ID 时,它不会 可以使用不同的连接 ID 来区分数据包 通过不同的路径发送到该节点。

每个终端主机可以使用多个 IP 地址来提供连接。在 具体而言,Multipath 扩展支持以下场景。

  • 客户端使用多个 IP 地址,服务器仅侦听 一。
  • 客户端仅使用一个 IP 地址,服务器监听 几个。
  • 客户端使用多个 IP 地址,服务器监听 几个。

此提案不包括地址发现和管理。地址 并假设了设置或拆除路径的实际决策过程 由使用 QUIC 多路径的应用程序处理 外延。这足以解决上述第一个问题 场景。但是,本文档不会阻止将来的扩展 确定解决其余情况的机制。 此外,该提案仅指定了一个简单的基本数据包 调度算法,以提供一些基本的实现 指导。然而,更先进的算法以及潜力 预计会进行扩展以增强当前路径状态的信号传输 作为未来的工作。

1.1. 约定和定义

关键词“必须”、“不得”、“必需”、“应”、“不应”、 “应该”、“不应该”、“推荐”、“不推荐”、“可能”以及 本文档中的“可选”应按照 BCP 14 [RFC2119] [RFC8174] 中的描述进行解释,当且仅当它们出现在所有文件中时 大写字母,如此处所示。

我们假设读者熟悉 [QUIC-TRANSPORT] 中使用的术语。当本文档使用术语“路径”时,它指的是 到 [QUIC-TRANSPORT] 中使用的“网络路径”概念。

2. 高级概述

本文档中提出的对 QUIC 的多路径扩展可以同时利用 为单个连接交换非探测 QUIC 帧的不同路径。这与此形成鲜明对比 基本 QUIC 协议 [QUIC-TRANSPORT],其中包含连接迁移机制,该机制 仅选择一条路径来交换此类帧。

多路径 QUIC 连接作为常规 QUIC 连接从 QUIC 握手开始。 另见第 3 节。 对等方在握手期间使用 enable_multipath 传输参数来 协商多路径功能的利用率。 active_connection_id_limit 传输参数限制活动路径的最大数量 可以在连接期间使用。因此,多路径 QUIC 连接是已建立的 QUIC 连接,其中 enable_multipath 传输参数 已成功谈判。

要向现有多路径 QUIC 连接添加新路径,客户端需要启动路径验证 所选路径,如第 4 节中所述。 在此版本的文档中,QUIC 服务器不会启动创建 ,但它可以验证客户端创建的新路径。 只有在验证了关联的 4 元组后,才能使用新路径 通过确保对等方能够在该地址接收数据包 (参见 [QUIC-TRANSPORT] 第 8 节)。使用目标连接 ID 将数据包关联到在有效路径上使用的数据包号空间。此外, 目标连接 ID 的序列号用作数字标识符 在控制帧中。例如,端点发送一个PATH_ABANDON帧来请求其对等体 放弃发送方使用目标连接 ID 的路径 替换为包含在PATH_ABANDON帧中的序列号。

除了这些核心功能外,使用多路径 QUIC 的应用程序通常还会 需要其他算法来处理活动路径的数量以及如何使用它们 发送数据包。由于这些根据应用程序的要求而有所不同,因此他们的 规格超出了本文档的范围。

使用多个数据包编号空间需要改变 AEAD 的方式 如第 5.2 节所述,已申请数据包保护, 以及对关键更新的更严格限制,如第 5.3 节中所述。

3. 握手协商和传输参数

此扩展定义了一个新的传输参数,用于协商 在连接握手期间使用多路径扩展, 如 [QUIC-TRANSPORT] 中指定。新的传输参数是 定义如下:

  • 名称:enable_multipath(当前版本使用0x0f739bbc1b666d04)
  • 值:0(默认值)表示已禁用。

表 1 中列出了值字段的有效选项:

表 1enable_multipath的可用值
选择定义
0x0不支持多路径
0x1支持本文档中定义的多路径

如果对于任何一个端点,参数不存在或设置为 0, 端点必须回退到具有单个活动路径的 [QUIC-TRANSPORT],并且不得使用任何帧或 本文档中定义的机制。

如果参数设置为 1,则两个端点都必须使用非零连接 身份证。如果接收到enable_multipath参数设置为 1 并且携带的数据包 不包含非零长度的连接 ID,接收方必须将此视为类型的连接错误 TRANSPORT_PARAMETER_ERROR(在 [QUIC-TRANSPORT] 第 20.1 节中指定) 并关闭连接。

如果终结点收到传输参数的意外值 “enable_multipath”,则必须将此视为类型的连接错误 TRANSPORT_PARAMETER_ERROR(在 [QUIC-TRANSPORT] 第 20.1 节中指定) 并关闭连接。

此扩展不会更改任何传输参数的定义 在 [QUIC-TRANSPORT] 的第 18.2 节中定义。

符合 [QUIC-TRANSPORT] disable_active_migration 中的定义 还禁用多路径支持,但“在客户端对 preferred_address 传输参数“([QUIC-TRANSPORT]第 18.2 节)。

传输参数 “active_connection_id_limit” [QUIC-TRANSPORT] 限制了可用连接 ID 的数量,并且 限制并发路径的数量。对于 QUIC 多路径扩展 当 QUIC 中未公开任何连接 ID 时,此限制也适用 页眉。

4. 路径设置和删除

完成握手后,端点已同意启用 多路径功能,可以开始使用多个路径。本文档 不指定如何通过多个地址访问端点 向另一个端点播报这些地址。具体而言,如果 服务器使用 preferred_address 传输参数 clients 不应假定初始服务器地址和地址 此参数中包含的参数可以同时用于多路径。 此外,本文档 不讨论客户何时决定启动新路径。我们 在单独的文件中委托进行此类讨论。

要打开新路径,端点应在不同的路径上使用不同的连接 ID。 尽管如此,接收方仍可能会观察到在不同的设备上使用的相同连接 ID 4 元组,例如,由于 NAT 重新绑定。在这种情况下,接收器会做出反应 如 [QUIC-TRANSPORT] 第 9.3 节所述。

该提案为路径管理添加了两个多路径控制帧:

  • PATH_ABANDON帧,用于接收端放弃路径 (参见第 8.2 节)
  • PATH_STATUS帧来表示路径使用中的偏好 (参见第 8.3 节

所有新帧都以 1-RTT 数据包 [QUIC-TRANSPORT] 发送。

4.1. 路径启动

在 [QUIC-TRANSPORT] 之后,每个端点都使用NEW_CONNECTION_ID帧 发出可用的连接 ID 以访问它。在端点添加之前 通过启动路径验证来创建新路径,它必须至少检查是否至少 每端都有一个未使用的连接 ID。

如果传输参数 “active_connection_id_limit” 协商为 N, 服务器提供了 N 个连接 ID,并且客户端已经处于活动状态 使用 N 个路径,则达到限制。如果客户端想要启动 一条新路径,它必须退出已建立的路径之一。

协商多路径选项时,想要使用 其他路径必须首先启动地址验证过程 具有 [QUIC-TRANSPORT] 第 8.2 节中所述的 PATH_CHALLENGE 和 PATH_RESPONSE 帧。在收到来自 的数据包后 新路径上的客户端,如果服务器决定使用新路径, 服务器必须执行路径验证([QUIC-TRANSPORT]第 8.2 节) 除非它之前已经验证过该地址。

如果验证成功,客户端可以发送非探测的 1-RTT 数据包 在新的道路上。与 [QUIC-TRANSPORT] 第 9 节中的规范相反,服务器不得假设 在新路径上接收非探测数据包表示尝试 迁移到该路径。相反,服务器应该考虑新的路径 在哪些非探测数据包上被接收为可用 用于传输。

4.2. 路径状态管理

端点使用PATH_STATUS帧来通知对等方应 按照这些帧表示的首选项发送数据包。 请注意,端点可能不会遵循对等方的播发, 但PATH_STATUS框架仍然是一个明确的暗示信号 对于对等方使用路径的偏好。

PATH_STATUS帧描述了 2 种路径状态:

  • 将路径标记为“可用”,即允许对等方使用自己的逻辑 在可用路径之间分配流量。
  • 将路径标记为“备用”,即建议不应发送任何流量 如果有另一条路径可用,则在该路径上。

端点使用“目标连接 ID 序列号”字段 PATH_STATUS帧中确定路径状态将是什么 改变。请注意,PATH_STATUS帧 可以通过不同的路径发送。端点可以忽略PATH_STATUS帧 如果它会使所有路径在单个连接中不可用。

4.3. 路径关闭

每个端点都管理可用于的路径集 传输。在连接中的任何时候,每个端点都可以决定 放弃其中一条路径,例如,遵循本地更改 连接性或本地首选项的变化。端点放弃后 路径,则对等体将不会再接收任何非探测数据包 那条路。非探测数据包在 [QUIC-TRANSPORT] 的第 9.1 节中定义。

想要关闭路径的端点应使用显式请求来 通过发送PATH_ABANDON帧来终止路径(参见第 4.3.1 节)。请注意,虽然放弃路径会导致 连接 ID 停用,仅停用关联的连接 ID 不一定通告路径放弃(参见第 4.3.3 节)。 但是,空闲时间或数据包丢失等隐式信号可能是 终端主机检测路径闭合的唯一方法(参见第 4.3.4 节)。

请注意,[QUIC-TRANSPORT] 的其他显式关闭机制仍然存在 应用于整个连接。特别是,接收任何一个 CONNECTION_CLOSE([QUIC-TRANSPORT]第10.2节)或无国籍人 重置([QUIC-TRANSPORT] 的第 10.3 节)关闭连接。

4.3.1. 使用PATH_ABANDON帧关闭路径

两个端点,即客户端和服务器,都可以启动路径闭合, 通过发送PATH_ABANDON帧(参见第 8.2 节),其中 请求对等方停止发送具有相应目标连接 ID 的数据包。

PATH_ABANDON帧的发送方和接收方不应释放其资源 立即,但应至少等待电流的三倍 探测超时 (PTO) 间隔,如第 6.2 节中定义的 [QUIC-RECOVERY] 在发送RETIRE_CONNECTION_ID帧之前的最后一次发送数据包之后 用于相应的 CID。 这符合 [QUIC-TRANSPORT] 第 10.2 节的要求,以确保路径干净地关闭,并且延迟或重新排序数据包 被正确丢弃。 接收RETIRE_CONNECTION_ID帧的效果在 下一节。

通常,预计客户端会使用PATH_ABANDON帧 向服务器指示路径条件已更改,以便 该路径现在或将不再可用,例如在移动性的情况下 事件。因此,PATH_ABANDON帧向接收器推荐 不应再在该路径上发送任何数据包。 此外,RETIRE_CONNECTION_ID帧用于指示接收对等体 发送方不会发送与此关联的任何数据包 该路径上不再使用的连接 ID。 PATH_ABANDON帧的接收者也可以发送 一个PATH_ABANDON框架,表明自己不愿意接受 此路径上的任何数据包。

PATH_ABANDON帧可以在任何路径上发送, 不仅是要关闭的路径。因此,路径可以 即使该路径上的连接已经中断,也会被放弃。

可重传的帧,以前已在废弃的帧上发送 路径并被视为丢失,将在不同的位置重新传输 路径。

如果接收到QUIC的唯一活动路径的PATH_ABANDON帧 连接时,接收对等体应发送CONNECTION_CLOSE帧 并进入关闭状态。如果客户收到了PATH_ABANDON 帧,如果出现以下情况,它可能会尝试打开一个新路径 可用,并且仅在路径验证失败时启动连接关闭 或者从服务器接收到CONNECTION_CLOSE帧。同样地 服务器可以等待一小段有限的时间,例如,如果路径是一个 PTO 在发送 CONNECTION_CLOSE框架。

4.3.2. 拒绝新路径

端点可能会拒绝建立由其启动的新路径 在地址验证过程中对等。根据[QUIC-TRANSPORT],拒绝建立路径的标准方法 就是不发送PATH_RESPONSE以回应对等方的PATH_CHALLENGE。

4.3.3. RETIRE_CONNECTION_ID框架的影响

接收RETIRE_CONNECTION_ID帧会导致端点丢弃 与该连接 ID 关联的资源。具体而言,即终结点 不应再使用已停用的连接 ID 的序列号 任何控制帧,因为对等体将无法将这些帧关联到 一条路径,因此会忽略它们。这意味着也不需要端点 确认带有该连接 ID 的任何延迟数据包,因此, 它可以在之后删除用于发送确认的已接收数据包列表 接收RETIRE_CONNECTION_ID帧。

发送RETIRE_CONNECTION_ID帧的对等体可以使用 以前关联的相同 IP 地址和 UDP 端口 该连接 ID,但在执行此操作时必须使用不同的连接 ID。 如果不再有可用的新连接 ID,则终结点无法发送 这条路。例如,如果连接 ID 颁发者请求停用 在NEW_CONNECTION_ID帧中使用 Retire Before To 字段的连接 ID,但这样做 提供足够的新 CID。

请注意,即使对等体无法再在路径上发送,因为它没有 要使用的有效连接 ID,它仍然可以确认在路径上接收的数据包, 通过在另一条路径上发送ACK_MP帧(如果可用)。但也要注意, 由于没有与路径关联的有效 CID,因此另一端无法发送 包含连接 ID 序列号的多路径控制帧,例如 如PATH_ABANDON或PATH_STATUS。

如果对等体无法在路径上发送,并且路径上未收到任何数据,则空闲超时将关闭 路径。如果在空闲计时器过期之前,将发出新的连接 ID 通过其对等方,端点可以通过以下方式重新激活路径 在该路径上发送具有新连接 ID 的数据包。

如果发送方停用了仍由 在传输中的数据包中,它可能会接收引用已停用ACK_MP帧 连接 ID。如果发件人停止跟踪已停用的已发送数据包 连接 ID,这些将被虚假标记为丢失。为了避免这样的情况 在不保持已停用的连接 ID 状态的情况下出现性能问题,以及 端点应首先停止发送包含待停用的数据包 连接 ID,然后等待所有正在进行的数据包都为 确认或标记为丢失,最后停用连接 ID。

4.3.4. 空闲超时

[QUIC-TRANSPORT] 允许在连接处于空闲状态时关闭连接 太久了。定义了多路径 QUIC 中的连接空闲超时 作为“在空闲超时期间,任何路径上均未收到数据包”。 当只有一个路径可用时,服务器必须遵循规范 在 [QUIC-TRANSPORT] 中。

当有多个路径可用时,主机应监视 非探测数据包以及通过每个数据包发送的数据包的确认 路径。如果主机应停止在路径上发送流量,则至少在 [QUIC-TRANSPORT] 第 10.1 节中指定的空闲超时 (a) 未收到非探测数据包或 (b) 未收到 已确认通过此路径发送的非探测数据包,但可能会忽略该数据包 规则,如果它会取消所有可用路径的资格。为避免路径的空闲超时,端点 可以发送引发确认的数据包,例如包含PING帧的数据包 ([QUIC-TRANSPORT] 第 19.2 节)在那条道路上保持其活力。发送 定期 PING 帧还有助于防止中间盒超时,如 [QUIC-TRANSPORT] 的第 10.1.2 节所述。

服务器可以释放与路径关联的资源 在足够长的时间内未收到非探测数据包 path-idle 延迟,但只应最后释放资源 在空闲期间未收到任何流量时的可用路径 超时,如 [QUIC-TRANSPORT] 的第 10.1 节中所述。 这意味着,如果所有路径在空闲超时期间保持空闲状态,则连接 是隐式关闭的。

服务器实现需要选择子路径空闲超时作为交易 在保持资源(如连接 ID)处于使用状态之间处于关闭状态 时间过长或必须立即重新建立路径 在客户对路径放弃的虚假估计之后。

4.4. 路径状态

图 1 显示了端点路径可以具有的状态。

       o
       | PATH_CHALLENGE sent/received on new path
       v
 +------------+    Path validation abandoned
 | Validating |----------------------------------+
 +------------+                                  |
       |                                         |
       | PATH_RESPONSE received                  |
       |                                         |
       v                                         |
 +------------+     Path blackhole detected      |
 |   Active   |----------------------------------+
 +------------+                                  |
       |                                         |
       | PATH_ABANDON sent/received              |
       v                                         |
 +------------+                                  |
 |   Closing  |                                  |
 +------------+                                  |
       |                                         |
       | Path's draining timeout                 |
       | (at least 3 PTO)                        |
       v                                         |
 +------------+                                  |
 |   Closed   |<---------------------------------+
 +------------+

图 1路径的状态

在非最终状态下,主机必须跟踪以下信息。

  • 关联的 4 元组:元组(源 IP、源端口、目标 IP、 目标端口)由端主机用于通过路径发送数据包。
  • 关联的目标连接 ID:用于发送的连接 ID 路径上的数据包。

在“活动”状态下,主机还必须跟踪以下信息:

  • 关联的源连接 ID:用于接收的连接 ID 路径上的数据包。端点依赖于其序列号 发送路径控制信息,并明确确认属于该连接 ID 特定的数据包 数据包号空间。

处于“正在验证”状态的路径将执行路径验证,如所述 在 [QUIC-TRANSPORT] 的第 8.2 节中。终端主机不应发送 处于“正在验证”状态的路径上的非探测帧,因为它没有 保证数据包实际到达对等体。

如果 endhost 可以使用处于“Active”状态的所有路径 拥塞控制和流量控制当前允许发送 路径上的新数据。请注意,如果路径由于超时而变为空闲, 端点应在关闭路径之前发送PATH_ABANDON帧。

在“正在关闭”状态下,终端主机不应在此位置发送数据包 路径,因为无法保证对等方仍然可以映射 连接到的数据包。终端主机应等待 在移动路径之前确认PATH_ABANDON帧 设置为“已关闭”状态,以确保路径的正常终止。

当路径达到“已关闭”状态时,端主机会释放所有 path 的关联资源,包括关联的连接 ID。 端点应发送 RETIRE_CONNECTION_ID 帧以释放 [QUIC-TRANSPORT]之后的关联连接ID。考虑到 端点不应在“已关闭”的当前路径上发送数据包 状态下,端点可以在其他端点上发送RETIRE_CONNECTION_ID帧 可用路径。因此,终端主机无法发送或 在此路径上接收数据包。

5. 具有多个数据包号空间的多路径操作

QUIC 多路径扩展对每条路径使用不同的数据包编号空间。 这也意味着每条路径上都可以出现相同的数据包号,并且 数据包号不再是唯一标识符。这需要对 ACK 帧以及数据包保护,如以下小节所述。

协商多路径时, 每个目标连接 ID 都链接到一个单独的数据包号空间。 每个特定于 CID 的数据包号空间都从数据包号 0 开始。关注时 [QUIC-TRANSPORT]附录A.2中描述的数据包号编码算法, 已确认的最大数据包编号 (largest_acked) 在此新 CID 的数据包号空间中,对等体最初设置为“无”。

5.1. 发送确认

第 8.1 节中指定的ACK_MP框架用于 确认 1-RTT 数据包。 与 QUIC 版本 1 ACK 帧相比,ACK_MP帧额外增加了 包含接收方的“目标连接 ID 序列号”字段 以区分特定于连接 ID 的数据包号空间。

初始和握手数据包的确认必须使用 ACK 帧,如 [QUIC-TRANSPORT] 中指定。定义的 ACK 帧 在 [QUIC-TRANSPORT] 中,请勿携带 Destination Connection ID 序列号字段,用于标识数据包号空间。 如果多路径扩展已成功 协商后,1-RTT 数据包中的 ACK 帧确认发送的数据包 序列号为 0 的连接 ID。

一旦多路径支持的协商完成, 端点应使用 ACK_MP 帧而不是 ACK 帧来确认应用程序 数据包,包括 0-RTT 数据包,使用带有 握手结束后的序列号 0。

ACK_MP帧(在第 8.1 节中定义)应在路径上发送 它接收到带有它确认的数据包编号空间的连接 ID 的数据包。 但是,可以通过 ACK_MP 返回帧 不同的路径,基于发送ACK_MP帧的不同策略。

5.2. 数据包保护

QUIC 版本 1 的数据包保护在 [QUIC-TLS] 的第 5 节中指定。 数据包保护的一般原则不会因 QUIC 多路径。无需更改数据包保护密钥的设置, 初始密钥、标头保护、使用 0-RTT 密钥、接收 无序受保护的数据包,接收受保护的数据包, 或重试数据包完整性。但是,使用多个数字空间 对于 1-RTT 数据包,需要更改 AEAD 使用情况。

[QUIC-TLS的第 5.3 节指定了 AEAD 的用法,特别是 使用随机数 N,由组合数据包保护 IV 形成 替换为数据包编号。当使用多个数据包号空间时, 仅凭数据包编号并不能保证随机数的唯一性。

为了保证随机数的唯一性,随机数 N 为 通过将数据包保护 IV 与数据包编号相结合来计算 并使用目标连接 ID 序列号。

[QUIC-TRANSPORT] 的第 19 节对连接 ID 序列进行编码 作为可变长度整数的数字, 允许的值最大为 2^62-1;在本说明书中,范围小于 2^32-1 在更新数据包保护密钥之前,必须使用值。

为了计算随机数,一个 96 位的路径和数据包号由以下部分组成 按字节顺序排列的 32 位连接 ID 序列号,两个零位, 以及按网络字节顺序重建的 QUIC 数据包号的 62 位。 如果 IV 大于 96 位,则路径和数据包编号为 左填充 IV 大小的零。独家手术室 填充的数据包编号和 IV 构成 AEAD nonce。

例如,假设 IV 值为 , 连接 ID 序列号为 ,数据包编号为 , Nonce 将设置为 。6b26114b9cba2b63a9e8dd4f3aead6b2611489cba2b63a9e873e2

5.3. 密钥更新

QUIC 版本 1 的关键阶段位更新过程在 [QUIC-TLS] 的第 6 节中指定。 在此版本中,密钥更新的一般原则没有改变 规范。在 QUIC 版本 1 之后,Key Phase 位用于 指示用于保护数据包的数据包保护密钥。 Key Phase 位被切换以发出每次后续密钥更新的信号。 由于网络延迟,使用旧密钥保护的数据包可能会 到达时间晚于使用新密钥保护的数据包。因此 端点需要保留旧的数据包密钥,以允许这些延迟的数据包密钥 要处理的数据包,并且必须区分新密钥 和旧钥匙。在 QUIC 版本 1 中,这是使用数据包号完成的 使规则变得简单:如果数据包编号为 低于任何数据包编号帧的当前关键阶段。

在不同路径上使用多个数据包号空间时, 启动密钥更新过程时需要注意一些, 由于不同的路径使用不同的数据包号空间,但共享 一把钥匙。当在一条路径上启动密钥更新时,发送到 另一条路径需要知道过渡何时完成。否则 其他路径可能会发送带有旧密钥的数据包, 但是跳过在当前关键阶段直接发送任何数据包 跳转到下一个关键阶段发送数据包。当这种情况发生时, 由于端点只能保留两组数据包保护密钥 使用 1 位 Key Phase 位时,其他路径无法区分 应使用哪个密钥来解码收到的数据包,这会导致 密钥轮换同步问题。

要解决此类同步问题,如果密钥更新是 在一条路径上初始化时,发送方应至少发送一个数据包 在所有活动路径上使用新键。此外,端点不得 启动后续密钥更新,直到包含当前密钥的数据包 已在每条路径上得到确认。

根据 [QUIC-TLS的第 5.4 节,密钥阶段位受到保护, 因此,同时发送具有关键阶段位翻转的多个数据包 不应引起可链接性问题。

6. 示例

6.1. 路径建立

图 2 展示了新路径建立的示例 使用多个数据包号空间。

   Client                                                  Server

   (Exchanges start on default path)
   1-RTT[]: NEW_CONNECTION_ID[C1, Seq=1] -->
                       <-- 1-RTT[]: NEW_CONNECTION_ID[S1, Seq=1]
                       <-- 1-RTT[]: NEW_CONNECTION_ID[S2, Seq=2]
   ...
   (starts new path)
   1-RTT[0]: DCID=S2, PATH_CHALLENGE[X] -->
                   Checks AEAD using nonce(CID sequence 2, PN 0)
     <-- 1-RTT[0]: DCID=C1, PATH_RESPONSE[X], PATH_CHALLENGE[Y],
                                              ACK_MP[PID=2,PN=0]
   Checks AEAD using nonce(CID sequence 1, PN 0)
   1-RTT[1]: DCID=S2, PATH_RESPONSE[Y],
             ACK_MP[PID=1, PN=0], ... -->

图 2新路径建立示例

在图 2 中,端点首先交换 具有NEW_CONNECTION_ID帧的新可用连接 ID。 在此示例中,客户端提供了一个连接 ID(C1 和 序列号 1),服务器提供两个连接 ID (S1 为序列号 1,S2 为序列号 2)。

在客户端通过在该路径上发送数据包来打开新路径之前 有了PATH_CHALLENGE框架,就要检查是否有 每端可用的未使用的连接 ID。 在此示例中,客户端选择连接 ID S2 作为新路径中的目标连接 ID。

如果客户端已使用所有分配的 CID,则应将其停用 那些不再使用的,服务器应该提供 替换项,如 [QUIC-TRANSPORT] 中指定。 通常,需要像当前一样再提供一个连接 ID 在使用中,以允许新的路径或迁移。

6.2. 路径闭合

在此示例中,客户端检测到网络环境变化 (客户端的 4G/Wi-Fi 已关闭,Wi-Fi 信号正在减弱到阈值, 或RTT的质量或损失率越来越差)并希望关闭 初始路径。

图 3 展示了一个路径闭合示例。对于第一条路径, 服务器的 1-RTT 数据包使用 DCID C1,序列号为 1;这 客户端的 1-RTT 数据包使用 DCID S2,其序列号为 2。对于 第二条路径,服务器的 1-RTT 数据包使用 DCID C2,该 DCID C2 具有一个序列 2 个;客户端的 1-RTT 数据包使用 DCID S3,该 DCID S3 具有序列号 的 3.请注意,路径使用不同的数据包号空间。在本例中, 客户端将关闭第一条路径。它通过序列识别路径 其对等体用于通过该路径发送数据包的 DCID 编号, 因此使用DCID序列号1(与C1相关)。(可选)该 服务器确认路径关闭 通过指示 DCID 的序列号发送PATH_ABANDON帧 客户端用于发送该路径,该路径对应于序列号 2(S2 的)。客户和 服务器在收到RETIRE_CONNECTION_ID帧后可以关闭路径 对于那条路。

Client                                                      Server

(client tells server to abandon a path)
1-RTT[X]: DCID=S2 PATH_ABANDON[dcid_seq_num=1]->
                           (server tells client to abandon a path)
               <-1-RTT[Y]: DCID=C1 PATH_ABANDON[dcid_seq_num=2],
                                               ACK_MP[PID=2, PN=X]
(client retires the corresponding CID)
1-RTT[U]: DCID=S3 RETIRE_CONNECTION_ID[2], ACK_MP[PID=1, PN=Y] ->
                            (server retires the corresponding CID)
 <- 1-RTT[V]: DCID=C2 RETIRE_CONNECTION_ID[1], ACK_MP[PID=3, PN=U]

图 3关闭路径的示例。

7. 实施注意事项

7.1. 数字空间

第 1 节所述,当协商多路径时,每个 目标连接 ID 链接到单独的数据包号空间。 这在 [QUIC-TRANSPORT] 中指定的 QUIC 实现之间有很大的不同,它只需要管理 Initial 的三个数字空间, 握手和应用程序数据包。

实现具有多路径能力的QUIC将需要谨慎 对路径和数字空间之间的关系进行建模,如图所示 在图 4 中。

   +-------------------------+
   | CID received from peer: |
   | Previous Sender Number  |
   | Space                   |-- - - - - - +
   +-------------------------+
   +-------------------------+             |
   | CID received from peer: |
   | Sender Number Space     |             |
   +-------------------------+             v
                      ^             +----------------+
                      |             | Path (4 tuple) |
                      +-------------| - RTT          |
                +------------------>| - Congestion   |
                |                   |   state        |
                v                   +----------------+
   +-------------------------+             ^
   | CID provided to peer:   |             |
   | Receiver Number Space   |
   +-------------------------+             |
   +-------------------------+
   | CID previously used by  |-- - - - - - +
   | Peer: old Receiver      |
   | Number Space            |
   +-------------------------+

图 4发送和接收号码空间

路径由数据包通过的 4 元组定义 已接收和发送。在路径上发送的数据包将包括 当前用于该路径的目标连接 ID,已选中 从对等方提供的 CID 列表中。接收的数据包 在路径上携带对等方选择的目标 CID 提供给该对等方的列表。

CID 和路径之间的关系不是固定的。节点可以 决定轮换它使用的目标 CID,NAT 可能会决定 更改来自该路径的数据包将位于的 4 元组 收到。 执行工作必须管理这些不断变化的关系。

与给定的传输和接收相关联的数据 path 可以关联到“路径状态”,也可以关联到 发送方或接收方号码空间的状态。例如:

  • RTT 测量值和拥塞状态在逻辑上是关联的 使用 4 元组。如果数据启动,它们将保持不变 使用新的 CID 通过相同的 4 元组接收或发送。
  • 损失恢复的实施通常会维护以下列表 已发送但尚未确认的数据包。此类信息,以及 将用于发送的下一个 PN 的值为 与“发件人号码空间”逻辑关联,以及 与对等提供的 CID 一起使用,用于在路径上发送。
  • 发送确认需要跟踪 PN 已收到的数据包和先前发送的确认。这样 信息在逻辑上与“接收者号码空间”相关联, 以及与对等方用于在路径上发送的 CID。

当路径和 CID 之间的链接发生变化时,信息会绑定 对于现在未使用的 CID 在一段时间内仍然有用。例如 旧版中维护的要确认的数据包号列表 接收器号码空间仍可用于发送ACK_MP帧 对于该数字空间。同样,已发送的数据包列表,但 尚未确认与旧发件人号码的空间可以使用 在处理该数字空间的传入ACK_MP帧时。这样 数据不应在 CID 更改后立即丢弃,而是 仅在以后,例如当 CID 停用时。

7.2. 拥塞控制

使用 QUIC 多路径扩展时,发送方管理每个路径 [QUIC-TRANSPORT] 第 9.4 节中要求的拥堵状态。 但是,在 [QUIC-TRANSPORT] 中,只假定有一个活动路径,因此 要求是在路径迁移时重置拥塞控制状态。 通过多路径扩展,可以同时使用多个路径, 因此,每条路径都保持单独的拥塞控制状态。 这意味着不允许发送者在给定的路径上发送更多数据 比该路径的拥塞控制所指示的。

当多路径 QUIC 连接使用两个或多个路径时,没有 保证这些路径是完全不相交的。当两条(或更多路径)时 共享相同的瓶颈,使用标准的拥塞控制方案 可能会导致带宽分配不公平 多路径连接获得比竞争单一连接更多的带宽 路径连接。多路径 TCP 使用 LIA 拥塞控制方案 在 [RFC6356] 中指定以解决此问题。该方案可以 立即适应多路径 QUIC。其他耦合拥塞 已经提出了针对多路径TCP的控制方案,例如[OLIA]。

7.3. 计算路径RTT

确认延迟是两个单向延迟的总和,即延迟 在数据包发送路径上和所选返回路径上的延迟 对于致谢。当不同的路径有不同的时 特征,这可能会导致确认延迟发生变化 广泛。例如,考虑使用两者的多路径传输 地面路径,每个方向的延迟为 50 毫秒,并且 地球静止卫星路径,两者的延迟均为 300 毫秒 方向。确认延迟将取决于组合 用于分组传输和ACK传输的路径数, 如表 2 所示。

表 2使用多路径的 ACK 延迟示例
ACK 路径 \ 数据路径地球的卫星
地球的100毫秒350毫秒
卫星350毫秒600毫秒

使用 [QUIC-RECOVERY] 中指定的默认算法将导致 在次优性能下,计算平均 RTT 和标准 与一系列不同时延测量值的偏差不同 组合路径。同时,早期测试表明它是 希望通过最短路径发送 ACK,因为较短的路径 ACK 延迟可带来更紧密的控制回路和更好的性能。 测试还表明,发送 ACK 的副本是可取的 在多条路径上,如果路径突然丢失,则确保稳健性。

早期实施通过使用 时间戳,如 [QUIC-Timestamp] 中指定。当时间戳 存在的情况下,实现可以估计传输时延 在每个单向路径上,然后可以使用这些单向延迟来获得更多 高效实施恢复和拥塞控制 算法。

如果时间戳不可用,则实现可以估计一个 使用统计技术的方式延迟。例如,在示例中 如表 1 所示,实现可以使用“相同路径” 测量,以估计地面路径的单向延迟 每个方向约50ms,卫星路径约为50ms。 300毫秒。然后可以使用进一步的测量来维持估计值 单向延迟变化,使用类似于卡尔曼滤波器的逻辑。 但是统计处理很容易出错,并且使用时间戳 提供更可靠的测量。

7.4. 数据包调度

在常规 QUIC 连接上传输 QUIC 数据包受到监管 通过来自应用程序的数据到达和拥塞控制 方案。只能发送增加传输中字节数的 QUIC 数据包 当拥塞窗口允许时。 多路径 QUIC 实现还需要包含数据包调度程序 这决定了在拥塞窗口打开的路径中,路径 下一个 QUIC 数据包将发送到该数据包。大多数帧,包括 控制帧(PATH_CHALLENGE和PATH_RESPONSE是值得注意的 Exceptions),可以在任何活动路径上发送和接收。日程安排 是本地决定,基于应用程序的偏好和 实现。

请注意,这意味着端点可以发送和接收ACK_MP 帧位于与携带已确认内容的路径不同的路径上 包。合理的默认值ACK_MP包括在 路径 他们确认数据包,但接收者不得承担其 peer 会这样做。

7.5. 转播

同时使用多个路径可实现不同的 应对损失的重传策略,例如: a) 通过 相同的路径,b) 在不同的路径上重新传输丢失的帧或 专用路径,以及 c) 在多个路径上复制丢失的帧(不是 由于网络的原因,建议用于一般用途 开销)。虽然本文件不排除特定的 策略上,更详细的规范超出了范围。

7.6. 处理不同的 PMTU 大小

实现应注意处理跨 PMTU 的不同大小 多条路径。如果 PMTU 相对相似,则一个简单的选项是将所有路径的最小 PMTU 应用于 每条路径。这种方法的好处是简化了重传 作为最初在一条路径上发送的丢失数据包的内容可以进行处理 在另一条路径上,没有进一步的帧调度适配。

7.7. 保持活动

QUIC 规范定义了一个可选的保持活动过程,请参阅 [QUIC-TRANSPORT] 的第 5.3 节。 多路径扩展的实现应将此保持活动过程映射到多个路径。 某些应用程序可能希望确保一条路径保持活动状态,而其他应用程序可能更愿意保持活动状态 在连接生存期内有两条或多条活动路径。不同的应用程序可能需要不同的策略。 一旦实现决定了要保持活动的路径,它就可以通过发送 Ping 帧来实现 在空闲超时到期之前,在每条路径上。

7.8. 连接 ID 更改和 NAT 重新绑定

[QUIC-TRANSPORT] 的第 5.1.2 节表示端点 可以将它用于的连接 ID 更改为另一个可用的 ID 在连接过程中的任何时间。因此,连接的唯一更改 地址未发生任何更改的 ID 并不表示路径更改,并且 端点可以保持相同的拥塞控制和 RTT 测量状态。

虽然端点将连接 ID 分配给特定的发送 4 元组, 网络事件(如 NAT 重新绑定)可能会使数据包的接收方 观察不同的 4 元组。观察到 4 元组更改的服务器将 执行路径验证(请参阅 [QUIC-TRANSPORT] 的第 9 节)。 如果路径验证过程成功,则端点将设置 路径的拥塞控制器和往返时间 根据 [QUIC-TRANSPORT] 第 9.4 节的估计器。

[QUIC-TRANSPORT] 的第 9.3 节允许端点跳过 对等地址(如果最近看到过该地址)。但是,当 使用多路径扩展,并且端点具有多个地址,这些地址 可能会导致在不同路径之间切换,它应该保持 而是多个开放路径。

如果终结点在空闲期后使用新的连接 ID NAT 重新绑定会导致同一数据包上的 4 元组更改, 接收端点可能无法将数据包关联到 现有路径,因此会将其视为新路径。 这导致两个对等体的开放路径视图不一致, 然而,由于“旧”路径将不再起作用,它将默默地 空闲超时到期后关闭。

8. 新框架

所有新帧只能以 1-RTT 数据包发送,并且不得 使用其他加密级别。

如果端点从 其他加密级别,它必须返回MP_PROTOCOL_VIOLATION 作为连接错误并关闭连接。

所有特定于多路径的帧都与目标连接相关 ID 序列号。如果端点收到目标连接 ID 序列号大于之前发送给对等体的任何序列号,则必须 将此视为 MP_PROTOCOL_VIOLATION 类型的连接错误。如果 端点接收到多路径特定的帧 具有无法处理的目标连接 ID 序列号 (例如,因为连接 ID 可能已停用),它 必须静默忽略该框架。

8.1. ACK_MP框架

ACK_MP框架(TBD-00 和 TBD-01 型;实验使用 0xbaba00..0xbaba01) 是 [QUIC-TRANSPORT] 定义的 ACK 帧的扩展。是的 用于确认在不同路径上发送的数据包,使用 多个数据包号空间。如果帧类型为 TBD-01,则ACK_MP帧 还包含收到的关联 ECN 标记的 QUIC 数据包的总和 在连接到这一点上。

ACK_MP帧的格式如图 5 所示。

  ACK_MP Frame {
    Type (i) = TBD-00..TBD-01 (experiments use 0xbaba00..0xbaba01),
    Destination Connection ID Sequence Number (i),
    Largest Acknowledged (i),
    ACK Delay (i),
    ACK Range Count (i),
    First ACK Range (i),
    ACK Range (..) ...,
    [ECN Counts (..)],
  }

图 5ACK_MP帧格式

与[QUIC-TRANSPORT]中指定的ACK帧相比,以下 字段已添加。

目标连接 ID 序列号:

标识数据包号的连接 ID 的序列号 1-RTT 数据包的空间,由 ACK_MP 帧确认。

8.2. PATH_ABANDON框架

PATH_ABANDON帧通知对等方放弃路径。

PATH_ABANDON帧的格式如图 6 所示。

  PATH_ABANDON Frame {
    Type (i) = TBD-02 (experiments use 0xbaba05),
    Destination Connection ID Sequence Number (i),
    Error Code (i),
    Reason Phrase Length (i),
    Reason Phrase (..),
  }

图 6PATH_ABANDON帧格式

PATH_ABANDON帧包含以下字段:

目标连接 ID 序列号:

使用的目标连接 ID 的序列号 接收方将帧发送到放弃路径上的数据包。

错误代码:

一个可变长度整数,指示放弃的原因 这条路。

原因短语长度:

一个可变长度整数,指定原因短语的长度 以字节为单位。由于PATH_ABANDON帧不能在数据包之间拆分, 对数据包大小的任何限制也将限制可用于 一个原因短语。

原因短语:

闭合的其他诊断信息。这可以是 如果发件人选择不提供超出以下详细信息,则长度为零 错误代码值。这应该是一个 UTF-8 编码的字符串 [RFC3629], 尽管框架不携带信息,例如语言标签, 这将有助于除该实体以外的任何实体的理解 创造了文本。

应确认PATH_ABANDON帧。如果数据包包含 PATH_ABANDON帧被视为丢失,对等方应重复该帧。

8.3. PATH_STATUS框架

PATH_STATUS Frame 被端点用来通知对等体当前 一个路径的状态,对等体应根据 这些框架中表达的偏好。 PATH_STATUS帧的格式如图 7 所示。

  PATH_STATUS Frame {
    Type (i) = TBD-03 (experiments use 0xbaba06),
    Destination Connection ID Sequence Number (i),
    Path Status sequence number (i),
    Path Status (i),
  }

图 7PATH_STATUS帧格式

PATH_STATUS 帧包含以下字段:

目标连接 ID 序列号:

使用的目标连接 ID 的序列号 接收此帧的接收者通过路径发送数据包的状态更新 对应。

路径状态序列号:

一个可变长度整数,指定 为此PATH_STATUS帧分配的序列号。序列 数字必须单调递增,由发件人生成 同一连接中的PATH_STATUS帧。接收者 PATH_STATUS帧需要使用和比较序列号 分别针对每个目标连接 ID 序列 数。

“路径状态”字段的可用值为:

  • 1:待机
  • 2:可用

端点使用PATH_STATUS帧来通知对等方它是否愿意这样做 无论是否使用此路径。如果端点接收到PATH_STATUS帧 包含 1 待机状态,则应停止发送非探测数据包 在相应的路径上,直到它接收到新的PATH_STATUS帧 包含 2-可用状态,具有更高的序列号,指的是 相同的路径。

帧的接收可能会乱序。对等方必须忽略传入的 如果之前收到另一个PATH_STATUS帧,则PATH_STATUS帧 对于相同的目标连接 ID 序列号,请使用 路径状态序列号等于或高于路径状态 传入帧的序列号。

应确认PATH_STATUS帧。如果数据包包含 PATH_STATUS帧被视为丢失,对等方应仅重复该帧 如果它是为该路径发送的最后一个状态 -- 如 序列号。

9. 错误代码

多路径 QUIC 传输错误代码是 62 位无符号整数 遵循 [QUIC-TRANSPORT]

本部分列出了定义的多路径 QUIC 传输错误代码 可以在具有某种0x1c的CONNECTION_CLOSE帧中使用。 这些错误适用于整个连接。

MP_PROTOCOL_VIOLATION(实验使用0xba01):检测到的终点 未涵盖的协议合规性错误 更具体的错误代码。

10. IANA 注意事项

本文档定义了用于协商的新传输参数 为 QUIC 启用多个路径,并启用三种新的帧类型。《征求意见稿》定义 实验的临时值,但我们预计 IANA 会分配 如果草稿获得批准,则为短值。

应将表 3 中的以下条目添加到 “QUIC 协议”标题下的“QUIC 传输参数”注册表。

表 3QUIC 传输参数条目的添加
价值参数名称。规范
待定(当前版本使用0x0f739bbc1b666d04)enable_multipath第 3 部分

应将表 4 中定义的以下帧类型添加到 “QUIC 协议”标题下的“QUIC 帧类型”注册表。

表 4对 QUIC 帧类型条目的添加
价值帧名称规范
TBD-00 - TBD-01 (实验采用0xbaba00-0xbaba01)ACK_MP第 8.1 节
TBD-02(实验使用0xbaba05)PATH_ABANDON第 8.2 节
TBD-03(实验使用0xbaba06)PATH_STATUS第 8.3 节

表 5 中定义的以下传输错误代码应 被添加到“QUIC 传输错误代码”注册表中的“QUIC 传输错误代码”注册表中 “QUIC协议”标题。

表 5多路径 QUIC 的错误代码
价值法典描述规范
待定(实验使用0xba01)MP_PROTOCOL_VIOLATION多路径协议冲突第9节

12. 贡献者

本文档是作者的合作,结合了 三项建议。其他参与的贡献者也参与其中 最初的建议之一是:

13. 致谢

待定

14. 参考资料

14.1. 规范性引用

[QUIC-恢复]

艾扬格,J.,编辑。和 I. Swett, Ed.,“QUIC 损失检测和拥塞控制”,RFC 9002,DOI 10.17487/RFC9002,2021 年 5 月,<https://www.rfc-editor.org/rfc/rfc9002>。

[QUIC-TLS]

汤姆森,M.,编辑。和 S. Turner, Ed.,“使用 TLS 保护 QUIC”,RFC 9001,DOI 10.17487/RFC9001,2021 年 5 月,<https://www.rfc-editor.org/rfc/rfc9001>。

[QUIC-运输]

艾扬格,J.,编辑。和 M. Thomson, Ed.,“QUIC:基于 UDP 的多路复用和安全传输”,RFC 9000,DOI 10.17487/RFC9000,2021 年 5 月,<https://www.rfc-editor.org/rfc/rfc9000>。

[RFC2119]

Bradner, S.,“RFC 中用于指示需求级别的关键词”,BCP 14,RFC 2119,DOI 10.17487/RFC2119,1997 年 3 月,<https://www.rfc-editor.org/rfc/rfc2119>。

[RFC3629]

Yergeau, F.,“UTF-8,ISO 10646 的转换格式”,STD 63,RFC 3629,DOI 10.17487/RFC3629,2003 年 11 月,<https://www.rfc-editor.org/rfc/rfc3629>。

[RFC8174]

Leiba, B.,“RFC 2119 关键词中大写与小写的歧义”,BCP 14,RFC 8174,DOI 10.17487/RFC8174,2017 年 5 月,<https://www.rfc-editor.org/rfc/rfc8174>。

14.2. 信息性引用

[I-D.bonaventure-iccrg-调度员]

Bonaventure, O.、Piraux, M.、De Coninck, Q.、Baerts, M.、Paasch, C. 和 M. Amend,“多路径调度程序”,正在进行中,互联网草案,draft-bonaventure-iccrg-schedulers-02,2021 年 10 月 25 日,<https://datatracker.ietf.org/doc/html/draft-bonaventure-iccrg-schedulers-02>。

[奥利亚]

Khalili, R., Gast, N., Popovic, M., Upadhyay, U., and J. Le Boudec,“MPTCP 不是帕累托最优:性能问题和可能的解决方案”,第 8 届新兴网络实验和技术国际会议论文集,ACM,2012 年。

[QUIC-不变量]

Thomson, M.,“QUIC 的版本独立属性”,RFC 8999,DOI 10.17487/RFC8999,2021 年 5 月,<https://www.rfc-editor.org/rfc/rfc8999>。

[QUIC-时间戳]

Huitema, C.,“用于测量单向延迟的 Quic Timestamps”,正在进行中,Internet-Draft,draft-huitema-quic-ts-08,2022 年 8 月 28 日,<https://datatracker.ietf.org/doc/html/draft-huitema-quic-ts-08>。

[RFC6356]

Raiciu, C.、Handley, M. 和 D. Wischik,“多路径传输协议的耦合拥塞控制”,RFC 6356,DOI 10.17487/RFC6356,2011 年 10 月,<https://www.rfc-editor.org/rfc/rfc6356>。

作者地址

Yanmei Liu (editor)
Alibaba Inc.
Yunfei Ma
Alibaba Inc.
Quentin De Coninck (editor)
UCLouvain
Olivier Bonaventure
UCLouvain and Tessares
Christian Huitema
Private Octopus Inc.
Mirja Kuehlewind (editor)
Ericsson
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值