RFC-0099:推出「zx_socket_set_disposition」

RFC-0099:引入「zx_socket_set_disposition」
狀態已接受
領域
  • 核心
說明

導入 `zx_socket_set_disposition` 以將 `zx_socket_closure` 取代為可復原的作業。

問題
更小鳥
作者
審查人員
提交日期 (年月分)2021-05-06
審查日期 (年-月-日)2021-06-03

摘要

導入 zx_socket_set_disposition 以取代 zx_socket_shutdown。新的系統呼叫能夠還原關閉作業,藉此擴充舊系統。

導入 ZX_RIGHT_MANAGE_SOCKET,並需要在新的 Sys 呼叫中。所有透過 zx_socket_create 新產生的帳號代碼都會有上述權限。

提振精神

以復原作業取代關閉的動機

我們在 fdio 中有一個精細的狀態機器,以因應未連線的串流網路通訊端是否接受寫入。狀態機器的本機狀態較難傳播至其他程序中的重複通訊端,以及用來驅動本機狀態的遠端狀態 (Zircon 通訊端上的使用者信號)。由於通訊端處於「開放」狀態,因此通訊端必須「開放」,因此必須避免這些體操上的 I/O 狀態「已連線」(還有透過外部方式)。

需要新權利的動機

Zircon 電源插座今日過於寬鬆。由於 zircon 通訊端可以複製 (並處於實際執行中),因此擁有寫入權限的單一控制代碼可以修改所有帳號的通訊端狀態。這個問題會使這個問題更嚴重,因為允許按照這裡提議復原關閉作業。

總整理

將通訊端關閉改為可復原作業,同時禁止未獲權的控制代碼啟動,將允許網路堆疊實作以完全驅動通訊端狀態。

通訊端在提供給用戶端之前可以先關閉,這樣就不必使用 fdio 中上述的狀態追蹤。

通訊端關閉可以完全由網路堆疊進行中介,由用戶端 FIDL 呼叫啟動,消除現行的競爭狀況 (例如 https://fxbug.dev/42140031)。

設計

FIDL 中定義 ZX_RIGHT_MANAGE_SOCKET

擴充 bits rights

library zx;

bits rights : uint32 {
  MANAGE_SOCKET = 0x00100000;
};

rights.md 中的文件 ZX_RIGHT_MANAGE_SOCKET

附加至資料表:

正確 推測的權限
ZX_RIGHT_MANAGE_SOCKET 允許透過 zx_socket_set_disposition 變更通訊端處理機制

FIDL 中定義 zx_socket_set_disposition

新增至 protocol socket

library zx;

protocol socket {
  /// Set disposition of writes.
  socket_set_disposition(handle:<SOCKET, rights.MANAGE_SOCKET> handle, uint32 disposition, uint32 disposition_peer) -> (status status);
}

/reference/syscalls/socket_set_disposition.md 中的 zx_socket_set_disposition 文件

說明

zx_socket_set_disposition 會設定通訊端控點及其對等點的 zx_socket_write 呼叫處理機制。

可以使用的有效處理旗標:

ZX_SOCKET_DISPOSITION_WRITE_DISABLED:停用指定通訊端端點的寫入功能。設定完成後,寫入指定通訊端端點的作業就會失敗,並顯示 ZX_ERR_BAD_STATE。在消耗指定通訊端端點中的所有資料緩衝後,系統會持續讀取來自指定通訊端端點的資料,但之後會失敗並顯示 ZX_ERR_BAD_STATE

ZX_SOCKET_DISPOSITION_WRITE_ENABLED:為指定的通訊端端點啟用寫入功能。設定完成後,寫入及讀取來自指定通訊端端點的作業將分別依 zx_socket_writezx_socket_read 所指定的行為。

在有緩衝資料的通訊端端點上指定 ZX_SOCKET_DISPOSITION_WRITE_ENABLED 無效,否則會導致 zx_socket_set_disposition 傳回 ZX_SOCKET_DISPOSITION_WRITE_ENABLED,且不會執行任何動作。

如果在 dispositiondisposition_peer 中同時指定 ZX_SOCKET_DISPOSITION_WRITE_DISABLEDZX_SOCKET_DISPOSITION_WRITE_DISABLED,則會導致 zx_socket_set_disposition 傳回 ZX_SOCKET_DISPOSITION_WRITE_DISABLED,且不會執行任何動作。

退貨價值

zx_socket_set_disposition() 在成功時傳回 ZX_OK

錯誤

ZX_ERR_BAD_HANDLE 帳號代碼不是有效的帳號代碼。

ZX_ERR_BAD_STATE dispositiondisposition_peer 包含 ZX_SOCKET_DISposition_WRITE_ENABLED處理常式,是指在指定的通訊端端點上具有緩衝資料的通訊端。

ZX_ERR_WRONG_TYPE 帳號代碼不是通訊端控制代碼,

ZX_ERR_ACCESS_DENIED 帳號代碼沒有 ZX_ERR_ACCESS_DENIED

ZX_ERR_INVALID_ARGS dispositiondisposition_peer 包含上方列以外的標記,或無效的標記組合。

遷移作業

實作後,zx_socket_shutdown 的現有使用情況會替換為等同對 zx_socket_set_disposition 的呼叫。完成必要的 ABI 轉換作業後,系統會移除 zx_socket_shutdown 及其相關選項。

實作

應完全在通訊端調度器內導入。

效能

這項變更對成效沒有實質影響。

人體工學

這項變更對人體工學沒有實質影響。

回溯相容性

這項變更具有回溯相容性,因為不使用新 API 介面的用戶端則不受影響。

安全性考量

這項變更可讓 fdio 程式碼變得更簡單,進而提高安全性。否則,這項變更對安全性沒有實質影響。

隱私權注意事項

這項變更對隱私權沒有實質影響。

測試

這項功能將使用系統呼叫的單元測試,並以新機器取代已註冊 fdio 狀態機器的部分。

說明文件

zx_socket_writezx_socket_read 會更新為參照 zx_socket_set_disposition,而不是 zx_socket_shutdown

其他說明文件將如實作章節所述進行更新。

缺點、替代項目和未知

您可以不新增 Syscall,而是在 zx_socket_shutdown 中新增標記,藉此還原其行為。這種做法的好處是避免加入新字詞 (發布) 顯然不符合行為。繼續使用 zx_socket_shutdown 的主要缺點是,其接受的標記並不直覺易用;ZX_SOCKET_SHUTDOWN_READ 不會執行 tin 所說的內容 (不允許對等點寫入,而非不允許讀取)。

如果資料通訊端中的指定方向存在,則「解除關閉」的行為即為產生錯誤。或者,您也可以選擇更嚴格的選項來防止非預期的結果。

你可以使用現有權利,不能建立新的權利。對於現有權利的問卷調查顯示,沒有任何現有權利適用於這個用途。

光憑這項設計無法完全解決串流通訊端的狀態傳播問題。這項提案的替代方案是更全面的方法,能完全消除 fdio 串流通訊端狀態機器。這類提案也一定會包含這個提案。

優先藝術與參考資料

串流通訊端語意是依據其在其他作業系統中的行為定義,因此需要區分已連線的通訊端和未連線的通訊端。