| RFC-0099:導入 `zx_socket_set_disposition` | |
|---|---|
| 狀態 | 已接受 |
| 區域 |
|
| 說明 | 導入 `zx_socket_set_disposition`,以可逆作業取代 `zx_socket_shutdown`。 |
| 問題 | |
| Gerrit 變更 | |
| 作者 | |
| 審查人員 | |
| 提交日期 (年-月-日) | 2021-05-06 |
| 審查日期 (年-月-日) | 2021-06-03 |
摘要
導入 zx_socket_set_disposition 以取代 zx_socket_shutdown。新的系統呼叫擴充了舊版,可讓您還原關機作業。
導入 ZX_RIGHT_MANAGE_SOCKET 並在新系統呼叫中要求使用。透過 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_write 和 zx_socket_read 中所指定。
如果插座端點已緩衝處理資料,則無法指定 ZX_SOCKET_DISPOSITION_WRITE_ENABLED,否則 zx_socket_set_disposition 會傳回 ZX_ERR_BAD_STATE,且不會採取任何動作。
在 disposition 或 disposition_peer 中同時指定 ZX_SOCKET_DISPOSITION_WRITE_DISABLED 和 ZX_SOCKET_DISPOSITION_WRITE_ENABLED 無效;這麼做會導致 zx_socket_set_disposition 傳回 ZX_ERR_INVALID_ARGS,且不會採取任何動作。
傳回值
zx_socket_set_disposition() 會在成功時傳回 ZX_OK。
錯誤
ZX_ERR_BAD_HANDLE handle 不是有效的控制代碼。
ZX_ERR_BAD_STATE disposition 或 disposition_peer 包含 ZX_SOCKET_DISPOSITION_WRITE_ENABLED,且 handle 參照的插座在指定的插座端點上具有緩衝資料。
ZX_ERR_WRONG_TYPE handle 不是通訊端控制代碼。
ZX_ERR_ACCESS_DENIED handle 沒有 ZX_RIGHT_MANAGE_SOCKET。
ZX_ERR_INVALID_ARGS disposition 或 disposition_peer 包含上述清單以外的旗標,或無效的旗標組合。
遷移
實作完成後,系統會將現有的 zx_socket_shutdown 用法,替換為對 zx_socket_set_disposition 的對等呼叫。完成必要的 ABI 轉換後,系統會移除 zx_socket_shutdown 和相關聯的選項。
實作
實作作業應完全在插槽調度器中進行。
效能
這項變更對效能沒有重大影響。
人體工學
這項變更對人體工學沒有重大影響。
回溯相容性
這項變更具有回溯相容性,因此不會影響未使用新 API 介面的用戶端。
安全性考量
這項變更可簡化 fdio 程式碼,進而提升安全性。這項變更對安全性沒有重大影響。
隱私權注意事項
這項異動對隱私權沒有重大影響。
測試
這項功能會透過系統呼叫的單元測試進行測試,並以新機制取代已測試的 fdio 狀態機部分。
說明文件
zx_socket_write 和 zx_socket_read 將更新為參照 zx_socket_set_disposition,而不是 zx_socket_shutdown。
其他文件將如實作章節所述更新。
缺點、替代方案和未知事項
與其新增系統呼叫,不如在 zx_socket_shutdown 中新增旗標,允許反向操作。這種做法的好處是可避免導入新字詞 (處置),因為這與行為顯然不相符。繼續使用 zx_socket_shutdown 的主要缺點是,它接受的標記不直覺;ZX_SOCKET_SHUTDOWN_READ 的功能與其名稱不符 (它會禁止同層級寫入,而非禁止讀取)。
「unshutdown」的行為指定為:如果資料存在於插座的指定方向,則會產生錯誤。您也可以選擇允許該作業成功執行;為避免產生非預期的後果,我們選擇較嚴格的選項。
您可以沿用現有權利,不必建立新權利。現有權利調查顯示,沒有任何現有權利適合這個用途。
單靠這項設計,並無法完全解決串流通訊端的狀態傳播問題。這項提案的替代方案是更全面的做法,目標是完全淘汰 fdio 串流通訊端狀態機器。這類提案必然也會包含本提案。
既有技術和參考資料
串流通訊端語意實際上是由其他作業系統中的行為所定義,因此需要區分已連線和未連線的通訊端。