RFC-0228:FDomain:遠端控制 Fuchsia 目標

RFC-0228:FDomain:遠端控制 Fuchsia 目標
狀態已接受
區域
  • 開發人員
  • 測試
說明

推出新的通訊協定,可用於在遠端 Fuchsia 裝置上執行任意 FIDL

問題
變更
  • 858944
作者
審查人員
提交日期 (年/月)2023-05-22
審查日期 (年/月)2023-10-04

摘要

本提案概述了 FDomain,這項新機制可以在開發主機的 Fuchsia 目標上,與 FIDL 服務通訊。FDomain 會支援 FFX 指令列工具的功能,取代現行的 Overnet 通訊協定。

提振精神

FFX 為元件階層公開的 FIDL 通訊協定提供更多或更少的任意存取。這可讓您輕鬆開發各種工具和外掛程式,並展現出與 sl4f 類似的自動化整合測試和功能。

FFX 會透過 Overnet 與裝置端 FIDL 通訊。Overnet 是一種點對點通訊協定,可讓 Fuchsia 核心控點透過網路共用。Fuchsia 裝置可以透過 Wi-Fi 將頻道傳送給開發人員主機,主機端 Fuchsia 模擬程式庫則可讓管道本身在裝置上執行時使用。Rust 的 FIDL 繫結可透過這些管道在主機上進行編譯,以便 FIDL 從主機與目標通訊。

Overnet 的方法有很多缺點:

  • 在主機上模擬核心控點一律不完美。控點僅限單一程序使用,而且必須使用額外的 Overnet 連線,才能在主機上的程序之間移動。其中完全缺少某些機制,例如 zx_channel_call。
  • 對帳號代碼產生錯誤報告的設計方式不是採用複雜且可順暢的網路堆疊。任何因 Overnet 帳號代碼而發生服務中斷的問題,都會回報為 PEER_CLOSED,且不再提供進一步資訊。
  • 核心控點的設計不適合透過網路進行 Proxy 處理。Overnet 是在沒有充分的諮詢核心團隊的情況下,才經過設計與實作。因此,現有的 API 無法正確實作部分功能 (例如物件信號),而且可能還是不可行。
  • 對 VM 等特定物件執行 Proxy 處理的承諾,且讓這些控點在主機上遠端運作的行為與在目標上的本機相同,是完全不可能支援 VMO 等特定物件。

除了這種做法的問題外,Overnet 的特定設計和實作也有一些缺點:

  • Overnet 所使用的低階通訊協定 (用來協調串流) 是以 FIDL 編寫,但請勿按照其設計使用 FIDL 的方式使用。而是在類似 protobuf 的角色中提供服務,用於指定封包的二進位形狀,但不會在傳輸過程中扮演任何角色。這會導致 FIDL 團隊無法管理,因而導致 Overnet 容易受到 FIDL 傳輸格式變更的影響,因為在一般傳輸過程中運作的 FIDL 使用者可能因此受到影響。
  • Overnet 的程式碼過於複雜,會採用經證實難以偵錯的非同步模式。
  • Overnet 是設計成點對點網狀網路而設計,為目前的用途多添一層複雜。

相關人員

講師:

hjfreyer@

審查者:

abarth@ cpu@ ianloic@ mgnb@ mkember@ slgrady@ wilkinsonclay@

社群媒體化:

並在 Fuchsia 工具團隊中討論 FDomain 的設計,而核心和 FIDL 團隊也會看到一項基本提案,而這兩個團隊都會提供意見回饋。

相關規定

FDomain 應允許主機連線至 Fuchsia 目標,並在設定好時透過 FIDL 與服務通訊,方式與目標上的元件大致相同。與 Overnet 一樣,我們會支援與較低層級核心基本功能 (特別是管道) 的通訊,並在該通訊之上實作 FIDL 繫結。Overnet 目前支援透過 Proxy 管道、通訊端、事件和事件組合,因此可以用來與未傳輸這些類型外部處理的任何 FIDL 通訊協定進行通訊。此處將指定 FDomain 視為支援同一組帳號代碼類型,但必須提供明確路徑,才能支援最多的 Fuchsia 控制類型,希望所有處理類型都受到支援。VMO 對多個應用程式特別感興趣,且可能會立即做為未來工作領域。請注意,並非所有帳號代碼類型的作業都能在遠端情境中呈現 (例如從遠端對應及取消對應 VMO),但 FDomain 希望盡可能針對每種帳號代碼類型盡可能提供大量能力。

如同上述內容,FDomain 應在線上呈現抽象層,允許直接使用核心介面,但不會影響這些介面的假設。許多限制的原因,都是因為對主機的呈現控點和 Proxy 模型來說,其對主機的轉移和 Proxy 模型與原始支援集以外的處理類型不相容。

FDomain 的設計會假設能夠在目標和主機之間交換可靠且已排序的資料元。這種實作方式應容易在 TCP 或 SSH 連線之上,使用一些額外的通訊協定層,或在 USB 大量端點上實作。這類傳輸的具體情況不在核心通訊協定的範圍內。

不同於 Overnet,FDomain 不提供任何能自動探索或建立目標的連線。FFX 並未仰賴 Overnet 對這些函式的實作。與 Overnet 不同的是,FDomain 只是端點對端點通訊協定,而不是網狀網路通訊協定。

FDomain 應要能偵測通訊協定版本不相容的情況,以便這些工具可以輕鬆找出造成問題的原因。您很難預見日後可能會發生哪種相容性問題,但一般來說,FDomain 也應可與不相容的版本互通。如果 FDomain 直接使用 FIDL,必須使用 FIDL 團隊自行維護的設施,確保傳輸格式相容性,並改回使用 FIDL。

User API 的相關規定

雖然要正確設計時,FDomain 通訊協定及其直接公開的語意相當重要,但對使用者直接顯示的 API 也有一些重要限制。這些欄位會採用主機端的 Rust Crate 形式,可提供從主機連線至 FDomain 的功能。

雖然 FDomain 刻意顯示 Zircon 的確切模擬,但也必須支援不會中斷 Zircon 「程式設計模型」的繫結。也就是說,處理主機在 FDomain 中的帳號時,使用 Zircon 程式碼的控點時,不應有細微或令人意外的差異。

除了這個 RFC 的範圍外,如要確定 Zircon 和 FDomain 主機端 API 之間能夠完全允許哪些差異,則需接受 API 審查。不過我們會特別說明,為達成目標,FDomain 需要觀察一些預期的差異:

  • 對於控點執行 FDomain 動作通常需要 IO,因此我們無法實作 Zircon API 的非阻塞語意。Zircon 處理程序的 Rust 繫結包含每個處理常式的更高層級「非同步」版本,這些帳號代碼使用 Rust 的未來系統處理非同步作業。我們可能會在該層實作 FDomain 主機端程式庫,不提供較低層級的控點,直接存取非封鎖作業。這會導致建立物件之間的一些語意差異。此外,通常僅採用原始控制代碼的作業,而非非同步版本的作業 (例如在 FIDL API 中建立端點) 並無法使用 FDomain 區分作業。
  • FDomain 帳號代碼必須屬於遠端連線 FDomain 的一部分。在 API 中代表這些物件的 RAII 物件將由連線物件產生,而非建構,而且可能含有行為或類型屬性,以反映其生命週期連結至連線生命週期的事實。(由於這部分的設計已經發生過一些爭論,因此我們強調此 RFC 並未提供任何特定建議)。
  • FDomain 作業會傳回更豐富更豐富的錯誤類型,反映遠端通訊協定可能遇到的故障模式問題 (以及遠端情況下可負擔的更豐富的錯誤報告)。Rust 針對錯誤處理的程式設計慣例,應該能讓使用者輕鬆瀏覽。

設計

從概念上來說,FDomain 是一組可從遠端操控的控點。FDomain 通訊協定會透過 FIDL 通訊協定呈現這些作業。

FDomain 會連結至及操控主機,而 FDomain 和主機之間的連線屬於 FDomain 連線。FDomain 最多只能有一個連接的主機,這表示主機不應觀察其控制在 FDomain 中的控制代碼已關閉,或由其他演員寫入或讀取控制代碼。雖然恢復工作階段可能會是日後工作的重要領域,但針對本文件,我們會假設主機一律連線至新的 FDomain (這是預先填入的一組控點),且當主機中斷連線時,FDomain 會遭到刪除並關閉的控點。

核心通訊協定

因為 FDomain 的點是透過不支援傳輸核心控點的連線顯示 FIDL,且通常位於不支援這些控點的主機,因此 FDomain FIDL 本身無法使用其方法參數中的任何位置或傳回值。具體來說,resource 關鍵字一律不得出現在 FDomain 的 FIDL 規格中。

FDomain 的通訊協定訊息是設計為透過管道以外的媒體傳輸,因此我們假設訊息沒有大小限制,因此不會限制通訊協定中向量和其他結構的大小。

Error Reporting 為必要項目

所有方法都必須能夠傳回錯誤。由於錯誤類型具有擴充性,所以我們可以在未來所有方法中加入錯誤條件。

此外,這會強制所有方法成為雙向方法,這表示 (RFC-0138)RFC-0138 中指定的不明互動處理一律可向主機傳回不明序數的相關錯誤。這樣應該就能更輕鬆地實作回溯相容性案例,因為根據「智慧寄件者、調暗接收器」主體,主機上會顯示所有相容性錯誤。

處理 ID 分配

主機會透過 ID 參照 FDomain 中的每個帳號代碼。這些 ID 在通訊協定中會編碼為 32 位元無正負號整數,但「不應」是直接向主機公開的實際核心帳號代碼。

為減少在通訊協定中執行作業所需的來回行程,我們會盡可能使用主機端 ID 分配。也就是說,如果作業會導致在 FDomain 中產生新的帳號代碼,例如主機要求建立新管道或通訊端時,主機會提供新管道本身要使用的 ID 編號。這可讓通訊協定中的管道產生更佳的管道,因為主機可以提交在同一交易上針對該帳號處理的第一個作業所建立的要求,而不需要等待每項作業的回覆。

這項政策例外是從管道讀取資料,而這可能會產生任意數量的控制代碼。要求主機為可能會因讀取管道而產生的控制代碼分配 ID,因此在提交讀取要求時,必須指定複雜的封鎖語意,才能與串流讀取相容。因此,讀取頻道產生的帳號代碼將由 FDomain 本身指派。

啟動

當主機連線至 FDomain 時,系統會假設主機從背景資訊中填入幾個啟動控點。這些控點與要提供給新啟動元件的控點類似。FDomain 會允許主機以支援類比的方式擷取這些帳號代碼,並保留使用者研究,其中 FDomain 是元件拓撲中的節點。

處理作業

FDomain 會支援在 FDomain 內建立新的通訊端、管道、事件組合和事件。也支援結束和複製控點,以及在與 zx_handle_replace 類似的情況下,將帳號代碼替換為具有不同權利的新版本。

對於需要重試的讀取、寫入和其他作業 (也就是使用 ZX_ERR_SHOULD_WAIT 失敗),FDomain 通訊協定將實作懸掛式 get ,並在目標端執行必要的通訊埠等待作業。如此可避免要求主機手動設定通訊埠所需的大量往返行程發生。

穩定線編碼

FIDL 的交易格式不適合在 Fuchsia 管道以外傳輸。如果 FIDL 需要在其他情況下序列化,則建議使用永久標頭,如 RFC-0120 中所述。

永久標頭的常見用途是存放靜態儲存的 FIDL 資料。雖然一般情況下,FDomain 訊息不會透過管道傳送,但仍會以一般的要求/回應方式傳送和接收。

永久標頭和交易標頭都包含魔術編號和一系列相容性標記。交易標頭也會新增用於新彈性方法通訊協定的「動態旗標」欄位,以及交易 ID 和方法,這兩種欄位都需要用於網域網域訊息。

一開始,計畫是使用永久標頭,並手動新增交易 ID 和方法序數,建立新的合併標頭格式。FDomain 的所有方法具有彈性,因此動態標記欄位的值可以隱含。

審查時,FIDL 團隊發現合併的標題與他們僅使用一般 FIDL 交易標頭提議的交易標頭相似。此 RFC 將採用該提案,同時也瞭解 FIDL 維護者接受的任何方法,可能會改變交易標頭格式的波動。

實作

目標端網域支援可在單一 Rust Crate 中提供,而第一項整合商可能是遠端控制服務。

傳輸至裝置的最初可作為透過舊版 Overnet 通訊協定發布的通訊端,或做為 Said 通訊協定較低層中的額外電路。接著,我們可能會選擇透過 SSH 實作直接傳輸,或直接轉換為實作自訂傳輸。

從目標層面來看,我們需要更多工作。目前主機端的 FIDL 通訊方式是否採用 Overnet 機制,需要模擬 Fuchsia 核心基本功能,也就是存放在 fuchsia-async 程式庫中。FDomain 專為非 Fuchsia 目標所設計,因此不應仰賴這個模擬功能。為了達成這個目標,我們將要求 FDomain 使用者使用新的 Rust FIDL 繫結類型,且該繫結會在 FDomain 基元為基礎。這些基本功能代表 FDomain 中的個別帳號代碼,但不會試圖模擬 Fuchsia 核心介面。事實上,這些控點確實希望針對遠端物件進行處理的實際情況,顯然也很明確,因為其 API 可能會公開與該情境相關獨特故障狀況相關的錯誤。對比 Overnet,如果傳輸或內部通訊協定的實作失敗,使用者就會產生無差異的 ZX_ERR_PEER_CLOSED

遷移

FDomain 目標端實作必須仰賴用於操控控點的 Zircon API。由於 Overnet 提供這些 API,因此應該可以在 Overnet 節點之上執行 FDomain。

這將成為我們在 FFX 內遷移的初始策略。我們會在 FFX Daemon 中代管 FDomain,以便從舊版 Overnet 連線取得 RCS Proxy,並在其命名空間中公開此 Proxy。主機可以使用魔術啟動工具要求新的通訊端連線變成一般 Overnet 連線或 FDomain 連線 (目前的超網路連線會以魔法字串「CIRCUIT\0」為開頭,因此我們已尋找這個位置的魔術效果)。

然後,FFX 工具架構就可以為工具提供 Overnet 或 FDomain Proxy。如果已建立兩個連線,則可同時提供這兩種 Proxy。這樣我們應該就能輕易將個別工具遷移至 FDomain 主機端程式碼。Daemon 本身託管的服務對於使用 FDomain 並不方便,但其他架構壓力已開始鼓勵這些服務停用或重新思考。

由於 FFX 外掛程式一般只會使用 FIDL Proxy,因此我們應該可以遷移至目標直接託管的 FDomain 連線,不需要其他變更。我們應能夠平行支援頂層 Overnet 和直接 FDomain 連線,就像執行電路切換的 Overnet 遷移作業一樣。

效能

FDomain 的現有應用程式全都是由 Overnet 目前處理的開發人員工具。為衡量 Overnet 效能,開發人員工具通常沒有嚴格的延遲時間或大頻寬要求。

儘管如此,關於 Overnet 的效能問題已開始浮出,至少不用決定效能期望可能很高的情況。因此,請謹慎執行以下測試:

  • 與通訊端、封鎖和串流通訊的處理量。
  • 直接呼叫簡單介面時的 FIDL 延遲時間。
  • 重複進行 FIDL 呼叫時的延遲時間,也就是每次呼叫在回覆先前呼叫的管道發出時出現的延遲時間。這會建立處理建立作業在著重效能的應用程式中呈現的方式。

回溯相容性

FDomain 代表來自 Overnet 通訊協定的乾淨故障。在完全終止 Overnet 前,系統會先在一定的寬限期內保留兩種通訊協定,藉此保留回溯相容性。

安全性考量

FDomain 核心通訊協定不會直接處理驗證作業,且可允許任意存取其控制的集合。因此,建議您以這種方式部署,以便只為可以安全提供給存取者的處理,以及可在安全提供這類存取權的環境中進行存取。這些考量已經針對 Overnet 進行,因此接管應用程式應確保以下事項。

在日後的應用程式中,權限提升較擔心問題 (因權限提升而過於寬鬆的應用程式本質上是具有最高權限的應用程式),所以可能會想到攻擊者透過實際上不適合位於 FDomain 的 FDomain 操控攻擊類別。根據本文件中的指南,如果不使用實際核心處理編號做為 FDomain 通訊協定中的處理 ID,應可緩解這類攻擊的所有明顯向量。在 Rust 中實作 FDomain,也因為這種語言具有強烈的擁有權語意,導致這類攻擊更容易防禦。

隱私權注意事項

FDomain 適用於仍在開發階段的裝置。不應有獨特的隱私權疑慮。即使是在意料之外的應用,隱私權也不太可能發生獨特的隱私權問題,但安全性疑慮的問題不在此限。

測試

Overnet 成功,我們成功產生了在單一程序中託管的整合測試,也就是將一個執行個體的位元組輸出結果提供給另一個執行個體的輸入,藉此讓通訊協定狀態的多個執行個體互相連線。這應該能讓我們測試各種設定和拓撲。

涉及真實的連網元件的整合測試較難,但可能無法帶來太多附加價值,而且可能會在複雜的實體測試設定中,導入本身存在的破壞風險。我們將透過設施進行基礎架構的前置測試,並依據可用性變化擴大測試範圍。

說明文件

除了照常記錄實作項目之外,樹狀結構中也應存有固定形式的通訊協定規格。這主要包含這個 RFC 的「Design」部分文字內容,但也可以視需要進行調整,以便加入通訊協定延伸模組。

缺點、替代方案和未知

與 Overnet 相比,FDomain 可大幅降低複雜程度。而且必須從頭開始實作,而且不具備與 Overnet 的回溯相容性。

遠端工具通訊協定的替代設計空間相當龐大,因此考量假設必須採用新的通訊協定,這是一項很漫長又沒有效率的工作。我們可以透過 FIDL 選擇自訂二進位格式,藉此進一步掌控相容性。或者,我們可以提供處理序間通訊 (IPC) 機制,該機製完全無法代表核心物件,而是提供專用的自訂介面給工具。

如果 Fuchsia 的應用實例擴展,而 FDomain 的其他用途很可能是重複執行較少工作,且提供的通訊協定較少。例如,有人可以使用 FDomain 取代資料中心內的 Fuchsia 伺服器,將 SSH 取代為遠端管理傳輸,而不只是診斷工具。本文所述的 FDomain 通訊協定應該對一般用途大有助益,但我們無法確定該通訊協定會如何調度資源。

先前的圖片和參考資料

如要進一步瞭解該通訊協定,請參閱 Fuchsia 樹狀結構中的 Overnet 文件