RFC-0184:系統 Netstack 的 POSIX 相容性

RFC-0184:系統 Netstack 的 POSIX 相容性
狀態已接受
區域
  • 外部 ABI 相容性
  • 網路堆疊
說明

說明在 Fuchsia 上支援類似 POSIX 的網路 API 的政策。

問題
Gerrit 變更
作者
審查人員
提交日期 (年-月-日)2022-07-15
審查日期 (年-月-日)2022-08-17

摘要

Fuchsia 的目標是透過 fdio 和系統 netstack,向元件公開與 POSIX 相容的網路 API。此外,它也支援其他以 POSIX 為導向的作業系統常見的非 POSIX 功能。

提振精神

Fuchsia 現有的系統網路堆疊是以 Linux 相容性為目標的核心建構而成。由於我們正計畫更換這個網路堆疊,因此相容性問題一再浮現。這項提案要求任何系統網路堆疊都必須以類似 POSIX 的 API 為目標,因此可解決上述問題。

POSIX 網路介面說明元件存取網路資源的標準方式。支援 Fuchsia 元件的 POSIX 網路子集,可輕鬆 1) 在 Fuchsia 上重複使用現有程式碼,以及 2) 使用熟悉的 API 為 Fuchsia 編寫新程式碼。

利害關係人

誰會受到這項 RFC 是否通過的影響?(這個部分為選填,但建議填寫)。

協助人員:

hjfreyer@google.com

審查者:

  • abarth@google.com (RFC-0082 作者)
  • brunodalbo@google.com (網路堆疊)
  • dhobsd@google.com (網路政策)

已諮詢:

brunodalbo@google.com、hanjh@google.com、hjfreyer@google.com、 martinjeffrey@google.com、nickbrow@google.com、tamird@google.com、 wildenhain@google.com

社交:

這項 RFC 經過網路堆疊團隊的設計審查。

設計

本文中的「MUST」、「MUST NOT」、「REQUIRED」、「SHALL」、「SHALL NOT」、「SHOULD」、「SHOULD NOT」、「RECOMMENDED」、「MAY」和「OPTIONAL」等關鍵字,應按照 IETF RFC 2119 的說明解讀。

在 Fuchsia 裝置上,系統網路堆疊會公開數個 fuchsia.posix.socket FIDL 服務,為元件提供網路功能。雖然 FIDL 感知元件可以指定這些目標,但我們極力不建議直接使用。而是應在 fdio 相容性程式庫中連結,將 libc 系統呼叫轉換為 FIDL 服務呼叫。

Fuchsia 的 fdio 程式庫可做為 POSIX「有限子集」的翻譯層,翻譯成適當的 FIDL 服務。就網路功能而言,fdio 提供多項 POSIX 呼叫的實作項目,包括 socketsetsockoptgetsockoptreadwritesendrecv 等。FIDL 服務與 fdio 分層實作,可完整實作這些和其他呼叫。

本文的目標不是提供完整的系統呼叫清單,而是定義決定何時實作 POSIX 或對等系統定義的網路功能所用的條件。預期 fdio 和網路堆疊會視需要實作系統呼叫和選項,主要用於第一方 Fuchsia 程式碼,然後是其他應用程式需要時。本文不討論可使用 fdio 提供的系統呼叫實作的 POSIX 函式。

請注意,雖然這項提案規定 Fuchsia 必須提供與 POSIX 相容的網路介面,但並未要求使用該介面。特別是,未來規格或開發 Fuchsia 優先 API 時,不會有任何限制,可與 POSIX 一併實作。

實作

現有的 fdio 程式庫和系統網路堆疊已為元件提供大部分與 POSIX 相容的介面。這項提案旨在將目前非正式的決策編碼化,以期與類似 POSIX 的作業系統達到同等水準,並引導網路堆疊和 fdio 程式庫的未來開發作業。變更系統網路堆疊和 fdio 時,請務必考量下列三項原則:

符合 POSIX 規範

Fuchsia 的系統 netstack 和 fdio 程式庫旨在提供與 POSIX 指定網路 API 的相容性。以 POSIX 網路 API 為目標的元件,在連結 fdio 並路由適當的通訊端建立功能時,應可正常運作。

與對等系統的相容性

POSIX 規格未定義某些互動的行為,因此針對 POSIX 介面編寫的元件通常會預期特定作業系統或作業系統系列的行為,並將其納入考量。如果這種行為定義明確,且在多個類似 POSIX 的作業系統中一致,Fuchsia 的網路子系統應與其相符 (以下說明的少數情況除外)。如果對等系統的行為不一致,Fuchsia 不保證會與任何特定對等系統的行為相符。

允許行為差異

Fuchsia 網路子系統可能需要實作與對等系統不同的行為。當

  • 對等系統的行為不一致,
  • 實作與同層級系統一致的行為會造成安全風險,或
  • 由於 Fuchsia 的架構限制,實作一致的行為會很困難或不可能。

在這種情況下,分歧「應」有充分的動機、詳細的說明文件,並經過充分測試。此外,元件「應該」很容易觀察到行為差異 (例如傳回錯誤的 POSIX 系統呼叫)。

已知限制

POSIX 會使用多個全域 ID 空間,包括 UID、GID、PID 和檔案路徑。許多這類 ID 都會搭配內建功能支援使用,以限制對 POSIX 類似系統的網路作業存取權。包括但不限於:

  • 在相同位址上繫結通訊端時,SO_REUSEPORTSO_REUSEADDR 僅限於以相同 UID 執行的元件。
  • 在 Linux 上,只有以 CAP_NET_RAW 執行的應用程式,才能清除 SO_BINDTODEVICE 通訊端選項。
  • 在 Linux 上,只有以 CAP_NET_RAW 執行的應用程式,才能建立原始 IP 通訊端。
  • 在 Linux 上,將通訊端繫結至低編號的連接埠時,應用程式必須具備 CAP_NET_BIND_SERVICE (不過在近期的 macOS 版本上,這是非具備權限的作業)。

如果可行,Fuchsia 會支援這些行為,但前提是這些行為的功能可對應至 Fuchsia 概念,且可能需要考量 Fuchsia 的架構限制。舉例來說,POSIX 類型的系統會隱含使用程序的 UID,來設定通訊埠共用權限的範圍。由於 Fuchsia 沒有 UID,元件必須採取明確行動才能選擇加入連接埠共用,可能以額外呼叫 fdio 的形式。

效能

為正式支援 POSIX 網路介面,Fuchsia 的網路子系統將提供 API 的高效能實作項目。Fuchsia 網路堆疊和 fdio 已有重要的基準化工具,可運用 POSIX 介面。這項資料將用於評估效能提升幅度,以及偵測回歸情形。

人體工學

Fuchsia 以 POSIX 為目標,這是應用程式的知名常見介面,因此開發人員可以輕鬆移植現有程式碼,並透過熟悉的介面編寫新程式碼。雖然部分 POSIX 概念不會直接對應至 Fuchsia (例如 UID),但絕大多數的網路概念都會。以熟悉的網路介面為目標,可大幅提升在 Fuchsia 上開發及將程式碼移植到 Fuchsia 的體驗。

回溯相容性

這項提案並非原則異動,只是將非正式原則編纂成文。由於沒有導入任何變更,因此向後相容性考量極少。

安全性考量

這項 RFC 並未導入任何新的安全考量,因為它只是將現有的一組非正式原則編碼。此外,我們承諾提供與 POSIX 相容的 API,但這不代表我們不會在日後針對網路堆疊進行元件隔離或分片,以解決安全性問題。

隱私權注意事項

這項提案不會帶來任何新的隱私權考量,因為提案內容只是將已使用的 POSIX API 支援功能編碼化。

測試

Fuchsia 系統 netstack 是使用現有的相容性套件進行測試,該套件會檢查是否符合 POSIX 和 Linux (不過後者只是為了方便,並不代表隱含認可 Linux 行為)。這套測試有助於防止回歸,並透過編碼系統對 POSIX 呼叫的回應預期行為,引導日後的功能開發。Fuchsia 網路子系統與 POSIX 或類似 POSIX 系統之間有意為之的行為差異,會編碼並記錄在測試套件中。已知非蓄意差異也會經過編碼和記錄,並在 Fuchsia 的錯誤追蹤系統中加上標記。這項整合層級測試,加上系統網路堆疊內部現有的單元測試,可充分涵蓋 POSIX 相容性。

說明文件

這項提案需要額外提供兩項文件:

  1. 如何使用 fdio API 與系統 netstack 通訊的說明,以及
  2. 列出 Fuchsia 網路堆疊/fdio 與 POSIX/類 POSIX 系統行為之間的不同之處。

缺點、替代方案和未知事項

這項提案需要承諾在 Fuchsia 系統網路堆疊和 fdio 程式庫中,實作 POSIX 和同層級相容行為的重大子集。由於這項提案是現有計畫的正式版本,因此許多功能已存在。這項提案承諾 Fuchsia 會擴充現有的 API 介面,並長期支援。

雖然 POSIX 是廣為人知的標準,但設計時並未支援 Fuchsia 具備的功能或豐富的 IPC 規格機制。如要支援與 POSIX 類似的系統,必須為元件提供更受限的介面 (同步系統呼叫、未輸入型別的檔案描述元),並將這些概念硬塞進 Fuchsia 基本型別。此外,為 Fuchsia 元件採用類似 POSIX 的介面,可能會阻礙實用的 Fuchsia 優先網路 API 開發作業。

如果採取更激進的做法,Fuchsia 可以明確避開 POSIX 相容性,改用以 Fuchsia 為主的 API。由於大量 Fuchsia 系統服務程式碼已編寫完成,目標是類似 POSIX 的 API,因此這似乎既適得其反,又缺乏遠見。

就未知項目而言,主要預期類別是 POSIX 支援的實作不完整區域,以及 Fuchsia 相對於同層級作業系統的不相容行為。發生或發現這類情況時,必須加以處理並記錄。

既有技術和參考資料

  • POSIX 2017 規格列出 POSIX 相容系統的要求。
  • RFC-0082 說明 Fuchsia 的目標,即在 Fuchsia 上執行未修改的 Linux 程式。
  • gVisor 專案的網路程式碼是現有 Fuchsia 系統網路堆疊的核心。

附錄:導入決策個案研究

POSIX 的 setsockopt 函式提供程式碼方法,可在影響插座行為的插座上設定選項。POSIX 定義了多個選項標記,但相容系統可新增自己的自訂標記。其中一個相當常用的選項是 SO_REUSEPORT 選項,設定後,這個選項允許在完全相同的位址和通訊埠上建立 bind 套接字。由於其語意經過明確定義,且在多個系統 (包括 FreeBSD、macOS 和其他 BSD 衍生產品) 中保持一致,因此 Fuchsia 的網路堆疊可讓元件在 UDP 通訊端上設定 SO_REUSEPORT 選項。

Linux 和 BSD 衍生實作項目之間的差異之一,是 Linux 要求繫結至相同位址的通訊端必須屬於具有相同使用者 ID 的程序。SO_REUSEPORT由於 Fuchsia 的架構不允許類似的使用者 ID 概念,因此 Fuchsia 不會實作這項限制。

此外,Linux 實作的 SO_REUSEPORT 會導致行為不一致,具體取決於是否在呼叫 bind 前於通訊端上設定選項,然後清除,或完全未在通訊端上設定選項。由於依賴不可見的系統狀態,且行為定義不佳,因此我們決定不模擬 Linux 的行為。

詳情請參閱 https://fxbug.dev/42051599。