RFC-0241:SDK 接口中的显式平台 / 外部拆分

RFC-0241:SDK 接口中的显式平台 / 外部拆分
状态已接受
领域
  • FIDL
说明

更精确地表示 Fuchsia 接口的哪些部分可以在 Fuchsia 平台之外实现。

问题
Gerrit 更改
作者
审核人
提交日期(年-月-日)2024-01-29
审核日期(年-月-日)2024-04-09

摘要

Fuchsia IDK 未指定外部组件是否应实现 客户端或服务器。这样, 很难正确评估 对 Fuchsia API 的更改。此 RFC 提出了一种 采用 FIDL 编写为人类和机器可读的方法。这让广告主有机会 提高基于 Fuchsia 的产品的正确性和稳定性。

设计初衷

Fuchsia 系统界面的大部分内容都是以 FIDL 作为一组协议 通过这些协议进行交换协议与客户端的协议是不对称的 和服务器端,但 FIDL 声明是作为 SDK/IDK 未指定 Fuchsia 平台提供的接口 产品提供的外部组件适用于服务器端、 安全协议的一方或双方进行公开宣传

这种不精确性极大地限制了 可以安全地发送到 Fuchsia 系统界面, Fuchsia 平台的实现,通常是外部组件。在 大多数协议要么只有服务器 要么只有客户端 在 Fuchsia 平台中实现的功能,但这些信息在 一种可供工具检查或最终开发者发现的方式。

例如,如果属于系统接口一部分的类型包含 string:100(采用 UTF-8 编码时最多包含 100 个字节的字符串)和 之后我们意识到需要支持较长的字符串。如果该类型只是 从外部组件发送到平台组件的请求(在协议方法中) 请求),则可以安全地增加长度限制,因为 对包含该字符串的消息进行解码时,该组件对包含该字符串的消息 始终至少会 new 作为组件对它进行编码。该类型可能会从平台发送 组件添加到外部组件,那么其长度就无法安全地增加 因为针对平台中较新的 API 级别构建的组件 意外向外部组件发送格式错误的消息。

利益相关方

谁对是否接受此 RFC 有影响?

教员

由 FEC 指定通过 RFC 管理此 RFC 的人员 过程。

审核者

  • abarth@google.com
  • chaselatta@google.com
  • hjfreyer@google.com

已咨询

  • aaronwood@google.com
  • awolter@google.com
  • crjohns@google.com
  • mkember@google.com
  • pesk@google.com
  • surajmalhotra@google.com
  • wittrock@google.com

社交化

向所有员工传达了简明扼要的介绍,描述他们遇到的问题和建议 到这里就结束了

要求

关键字“必须”“不得”“必需”“会”“不会”“应” “不应该”“建议”“可以”和“可选”文档内容 如 IETF RFC 2119

我们必须能够指明哪些系统接口协议可以具有各自的 客户端和/或服务器,或两者均在平台或外部组件中实现。这个 必须以一种可供评估工具访问的方式 进行平台更改

这些信息应适用于在软件组装时运行的工具 并且可以在运行时供组件框架使用。此信息 应通过生成的 API 文档向最终开发者显示,以及 构建时检查。

为了在评估 Fuchsia 平台及其上构建的组件,必须构建外部组件 针对平台支持的稳定 API 级别进行开发。

设计

分析

平台 ABI Surface 作为整体的兼容性可细分为 考虑外部交换之间各个类型之间的兼容性, 包括在通道协议和 序列化和带外交换。

组件之间的所有 FIDL 数据交换都位于以下某个位置:

  • 通过组件进行交换的 FIDL 协议 框架协议功能。它们都带有 @discoverable 属性。
  • 通过非 FIDL 方式交换的 FIDL 协议,例如流程 args
  • 在文件中序列化和交换的 FIDL 类型(例如 组件清单)或定制的 IPC 传输。

假设整个 Fuchsia 系统接口 FIDL 的存在,对于每个根,我们可以 收集可以从客户端发送到服务器以及从 从服务器到客户端

协议

如果我们知道,对于每个“根”无论其客户端和服务器 在外部组件或平台组件中实现的功能时,我们可以收集 可以从外部组件发送到平台组件的一组类型; 从平台组件到外部组件,在平台组件和 相互连接

对于协议:

@discoverable
protocol {
    M(Req) -> (Resp);
}

考虑到我们允许客户端和服务器实现的位置,我们可以了解 请求的类型 (Req) 和响应 (Resp) 的类型可能在 组件 (E) 和平台组件 (P):

客户端 服务器 E 到 P P 到 E P 到 P E 到 E
E E 请求、回复
E P 请求 回复
E P、E 请求 回复 请求、回复
P E 回复 请求
P P、E 回复 请求 请求、回复
P、E E 回复 请求 请求、回复
P、E P 请求 回复 请求、回复
P、E P、E 请求、回复 请求、回复 请求、回复 请求、回复

平台代码一定会读出所表达的协议版本的超集 所以我们可以用以下方式了解类型约束是否可以 收紧或放松:

发件人 接收器 约束条件
外部 平台 无法收紧
平台 外部 无法放松
外部 外部 无法更改

因此,我们需要能够限制 。

几乎所有作为根的协议都通过组件框架进行交换 功能。那些不是低层次和深奥的东西。它们包括: fuchsia.io.Directory 和一些网络套接字控制通道协议 fuchsia.posix.socket。无需发明新方法来标记这些协议 作为通信根源,我们应将 @discoverable 的意义扩展到 纳入这些协议。事实上,函数中的 fuchsia.posix.socket,用于表示要执行的套接字控制协议的名称 是自动生成的。@discoverable

类型

目前,任何组件(外部或平台)代码都可以进行序列化或反序列化 原始字节中的任何非资源类型。为了让兼容性工具知道 在某些情况下,不会对 FIDL 类型进行序列化或反序列化, 明确标记在常规 FIDL 之外的组件之间传递的类型 IPC。

语法

协议

可发现的属性将会扩展,以指明可发现的位置 协议。默认情况下,协议被标记为 @discoverable 可能同时具有由外部组件和 平台组件

serverclient 可选属性列出了 可以实现这种端点。默认情况下,两个端点都可以 由任何组件实现

例如:

// All servers in the platform, all clients in external components.
@discoverable(client="external", server="platform")
protocol P {};

// All servers in external components, all clients in the platform.
@discoverable(client="platform", server="external")
protocol Q {};

// Only clients allowed in external components, both clients and servers allowed in the platform.
@discoverable(client="platform,external", server="platform")
protocol R {};

// Servers are only allowed in platform components. Clients are allowed anywhere.
// If both clients and servers are allowed that argument can (and should) be omitted.
@discoverable(server="platform")
protocol S {};

类型

FIDL 中将添加一个新的 @serializable 属性,以标记哪些类型 已序列化,并在 FIDL 协议以外的组件之间传递。

此属性只能在非 resource structtableunion

它有两个可选参数:readwrite。以上每个列均使用英文逗号 包含 platformexternal 的单独列表,指示平台 组件或外部组件需要读取或写入该类型。通过 每个参数的默认值为 "platform,external",表示它可以 从这类组件中读取和写入数据。

实现

FIDL 工具链

fidlc 将更新为接受 @discoverable 和 新属性@serializable。FIDL 绑定生成器 (fidlgen_*) 不会 尚未修改。

Fuchsia 系统接口

partnerpartner_internal 库中的所有可检测到的 FIDL 协议 将进行更新。大部分将被标记为@discoverable(server="platform") 指示外部组件应仅实现客户端,而应实现平台 组件可以实现客户端和服务器。有些(如fuchsia.io中的很多) 将标记为 @discoverable(),表示任何组件都可以实现 客户端和服务器少数几个(大多用于驾驶员)会带有标记 @discoverable(client="platform", server="external") 表示外部 组件应仅实现服务器,而平台组件应仅 实施客户端。

经过一些实验和原型设计之后, 直接用来计算每个协议所属的类别。 既不对组件图进行运行时检查,也不对 CML 进行静态评估 清除了所有分片。而是使用外部组件的清单 它们使用和提供的协议功能。

对于独立的数据类型,我们将查找各种语言的调用, 绑定的显式序列化 API,并注解其中使用的类型 。

兼容性工具

我们正在开发一种工具,用于评估不同版本 Fuchsia 系统接口的 FIDL IPC 部分。这种做法与 FIDL IR 并将纳入可检测属性中的信息。答 对此工具将要实施的兼容性规则的完整说明 将出现在另一个 RFC 中。

未来机遇

兼容性工具是对 FIDL 进行增强的动力所在 语法。不过,这些关于 Fuchsia 系统接口的更丰富信息 在其他地方证明有用。

FIDL 绑定

FIDL 绑定生成器可以了解自己是否正在构建 针对平台组件或外部组件并调整 其生成的代码,旨在鼓励开发者仅部署客户端和服务器, 确保协议的兼容性。

阻止任何不受支持的客户端或服务器会适得其反,因为 开发者需要能够在测试中模拟同行, 可以设置保护措施,不建议在非测试环境中使用。

可以更新独立序列化代码,以仅允许 标记为 @serializable 进行传入。

组件框架

在组件框架内,协议功能没有类型化。通常, 以其携带的 FIDL 协议命名,但这仅仅是一种惯例, 一个是违反规则。推断组件的协议的 用来与同行通信的 必须根据名称 以及所使用的协议

如果组件框架向其模型中添加了协议类型,那么这些工具 变得更简单、更可靠、更准确。

软件汇编

软件汇编通过配置、平台生成 Fuchsia 系统映像 组件和外部组件。它可以根据哪些因素 可能会由平台组件提供或外部拒绝 组建违反这些规则的商品。这样可以确保 所有者没有在无意中构建可保证兼容性的产品 Fuchsia 没有提供的功能,并帮助平台开发者避免将 以他们不希望支持的方式使用 API。

安全

了解协议功能的哪一端通过外部 / 可能有助于评估 系统。这可以通过临时方式完成,也可以集成到现有 工具。

性能

效果不会发生任何变化。

工效学设计

这需要明确系统中的一些假设 需要的准备工作要多一点,但可以大大简化系统, 如何理解和工作

向后兼容性

现有的 FIDL 库不会受到影响。不带参数的 @discoverable 仍然是有效属性。

最初,我们不希望对 属性,因为它们是版本控制的输入,对源代码或 运行时兼容性,需要广泛采用才能看到其优势。如果我们 更新 FIDL 绑定,以根据可发现内容进行更改 参数,因为更改它们可能会破坏它们 现有源代码

安全注意事项

未来可能会在这方面提供提升整体水平的机会 系统安全性。

隐私注意事项

测试

这样,您便可以更轻松地确保我们完全兼容 针对 Fuchsia 平台进行基准测试。 我们承诺与哪些协议兼容。

对于所有 fidlc 更改,我们将添加新的 fidlc 测试。

直到我们在组装时确认所有组件都遵循 才能确定 FIDL 文件中是否表示外部 / 我们在 SDK 中表示的平台拆分与 Fuchsia 的实际情况相符 产品。

文档

有几项 FIDL 文档需要更新:

缺点、替代方案和未知问题

我们可以保持现状,但这样会严重限制 我们可以支持的各种更改,或限制我们的工具 检查更改的安全性

我们可以用 FIDL 语言之外的外部 / 平台划分 API 工具(就像我们对 SDK 类别所做的那样),但由于这种分类 发生在声明级别,这会感觉不太符合人体工程学, 变得过时

不要使用 @discoverable 来标记 fuchsia.io.Directory 等协议, 我们可以想出一个等效属性,它对 但不支持协议功能。感觉 例如构建更复杂的功能

不要添加 @serializable 来标记带外交换的类型, 我们可以只编写占位符 FIDL protocol,这些变量使用 使用适当的属性进行了标记 @discoverable,以暗示这些类型 可以读取和写入这意味着会有一些协议永远不需要 往往很难说得通,也听起来很混乱。

我们不再使用像 @discoverable(server="platform", client="external") 这样的语法, 使用 @discoverable(platform="server", external="client") 已有一段时间 但当前的语法更易于理解。

先验技术和参考资料

不适用