Skip to content

Commit baaaab5

Browse files
hikejsclaude
andcommitted
feat(windows): TSI Phase 1 - Windows Socket abstraction layer
Implement Phase 1 of TSI (Transparent Socket Impersonation) for Windows. This phase provides a Rust-friendly abstraction over Winsock2 APIs, serving as the foundation for the complete TSI implementation. Components added: - WindowsSocket: Core socket wrapper around Winsock2 - AddressFamily: IPv4/IPv6 support - SockType: Stream (TCP) and Dgram (UDP) support - ShutdownMode: Socket shutdown control Features implemented: - Socket creation with family and type selection - Non-blocking I/O support via ioctlsocket(FIONBIO) - SO_REUSEADDR socket option - bind(), connect(), listen(), accept() - send(), recv() for data transfer - local_addr(), peer_addr() for address queries - shutdown() for graceful connection termination - Proper RAII with Drop implementation Address conversion: - SocketAddr ↔ SOCKADDR_IN/SOCKADDR_IN6 conversion - Support for both IPv4 and IPv6 - Proper byte order handling (network vs host) Testing: - Unit tests for socket creation - Non-blocking mode tests - Bind and listen tests - All tests passing Documentation: - TSI Windows feasibility analysis (docs/tsi-windows-feasibility.md) - Detailed technical analysis of TSI implementation challenges - 4-6 week implementation roadmap - Comparison with Linux/macOS TSI implementation Next phases: - Phase 2: TSI Stream Proxy (TCP) - 1-2 weeks - Phase 3: TSI DGRAM Proxy (UDP) - 1 week - Phase 4: Named Pipes support - 1 week - Phase 5: Integration and testing - 1 week This is the first step toward achieving 100% feature parity with Linux/macOS backends by implementing transparent socket impersonation on Windows. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 5bba554 commit baaaab5

4 files changed

Lines changed: 729 additions & 0 deletions

File tree

docs/tsi-windows-feasibility.md

Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
# TSI Windows 实现可行性分析
2+
3+
## 执行摘要
4+
5+
**结论:在 Windows 上实现完整的 TSI 功能在技术上可行,但需要大量工作(估计 4-8 周)。建议优先评估是否真正需要 TSI,或者 virtio-net 是否足够。**
6+
7+
## TSI 技术背景
8+
9+
### 什么是 TSI?
10+
11+
TSI (Transparent Socket Impersonation) 是 libkrun 的核心创新,允许 guest 进程直接使用宿主机的网络栈,无需虚拟网卡。
12+
13+
**工作原理:**
14+
1. Guest 内核通过 vsock 发送特殊的 TSI 命令(TSI_CONNECT, TSI_LISTEN 等)
15+
2. Host 端的 vsock 设备拦截这些命令
16+
3. Host 代表 guest 创建真实的 socket(TCP/UDP/Unix)
17+
4. 数据通过 vsock 在 guest 和 host socket 之间透明传输
18+
19+
### 当前实现(Linux/macOS)
20+
21+
**核心组件:**
22+
- `tsi_stream.rs`: TCP/Unix socket 代理
23+
- `tsi_dgram.rs`: UDP socket 代理
24+
- `muxer.rs`: TSI 命令处理和路由
25+
- `proxy.rs`: 代理抽象层
26+
27+
**依赖:**
28+
- `nix` crate: Unix 系统调用封装
29+
- `std::os::unix`: Unix 特定 API
30+
- Raw file descriptors (RawFd)
31+
- Unix domain sockets
32+
- POSIX socket API
33+
34+
## Windows 实现挑战
35+
36+
### 1. API 差异
37+
38+
| 功能 | Linux/macOS | Windows | 差距 |
39+
|------|-------------|---------|------|
40+
| Socket 创建 | `socket()` | `WSASocket()` | 不同 API |
41+
| 非阻塞 I/O | `fcntl(O_NONBLOCK)` | `ioctlsocket(FIONBIO)` | 不同机制 |
42+
| 文件描述符 | `RawFd` (int) | `SOCKET` (HANDLE) | 类型不兼容 |
43+
| Unix sockets | `AF_UNIX` | Named Pipes | 完全不同 |
44+
| 事件通知 | `epoll` | `IOCP` / `select` | 不同模型 |
45+
46+
### 2. 架构差异
47+
48+
**Linux/macOS 架构:**
49+
```
50+
Guest Kernel → vsock → TsiStreamProxy → Unix Socket API → Host Network
51+
```
52+
53+
**Windows 需要的架构:**
54+
```
55+
Guest Kernel → vsock → TsiStreamProxy (Windows) → Winsock2 API → Host Network
56+
```
57+
58+
### 3. 代码重写范围
59+
60+
需要重写的模块:
61+
-`tsi_stream.rs`: 完全重写(~500 行)
62+
-`tsi_dgram.rs`: 完全重写(~300 行)
63+
- ⚠️ `muxer.rs`: 部分修改(TSI 命令处理)
64+
- ⚠️ `proxy.rs`: 接口适配
65+
- ✅ 新增 `tsi_windows.rs`: Windows 特定实现
66+
67+
**估计工作量:**
68+
- 核心实现:2-3 周
69+
- 测试和调试:1-2 周
70+
- 文档和集成:1 周
71+
- **总计:4-6 周**
72+
73+
## 实现方案
74+
75+
### 方案 A:完整 TSI 实现(推荐)
76+
77+
**优点:**
78+
- 功能完整,与 Linux/macOS 对等
79+
- 最佳性能和透明性
80+
- 支持所有 socket 类型(TCP, UDP, Named Pipes)
81+
82+
**缺点:**
83+
- 工作量大(4-6 周)
84+
- 需要深入理解 Winsock2 API
85+
- 维护成本高
86+
87+
**实现步骤:**
88+
89+
#### Phase 1: Windows Socket 抽象层(1 周)
90+
```rust
91+
// src/devices/src/virtio/vsock/tsi_windows/socket_wrapper.rs
92+
93+
pub struct WindowsSocket {
94+
socket: SOCKET,
95+
family: AddressFamily,
96+
sock_type: SockType,
97+
}
98+
99+
impl WindowsSocket {
100+
pub fn new(family: AddressFamily, sock_type: SockType) -> io::Result<Self>;
101+
pub fn connect(&self, addr: &SocketAddr) -> io::Result<()>;
102+
pub fn bind(&self, addr: &SocketAddr) -> io::Result<()>;
103+
pub fn listen(&self, backlog: i32) -> io::Result<()>;
104+
pub fn accept(&self) -> io::Result<(Self, SocketAddr)>;
105+
pub fn send(&self, buf: &[u8]) -> io::Result<usize>;
106+
pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize>;
107+
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()>;
108+
}
109+
```
110+
111+
#### Phase 2: TSI Stream Proxy(1-2 周)
112+
```rust
113+
// src/devices/src/virtio/vsock/tsi_windows/stream_proxy.rs
114+
115+
pub struct TsiStreamProxyWindows {
116+
id: u64,
117+
cid: u64,
118+
family: AddressFamily,
119+
local_port: u32,
120+
peer_port: u32,
121+
socket: WindowsSocket,
122+
status: ProxyStatus,
123+
// ... 其他字段
124+
}
125+
126+
impl TsiStreamProxyWindows {
127+
pub fn new(...) -> Result<Self, ProxyError>;
128+
pub fn process_connect(&mut self, req: TsiConnectReq) -> Result<(), ProxyError>;
129+
pub fn process_listen(&mut self, req: TsiListenReq) -> Result<(), ProxyError>;
130+
pub fn process_accept(&mut self, req: TsiAcceptReq) -> Result<(), ProxyError>;
131+
// ... 其他方法
132+
}
133+
```
134+
135+
#### Phase 3: TSI DGRAM Proxy(1 周)
136+
```rust
137+
// src/devices/src/virtio/vsock/tsi_windows/dgram_proxy.rs
138+
139+
pub struct TsiDgramProxyWindows {
140+
id: u64,
141+
cid: u64,
142+
family: AddressFamily,
143+
local_port: u32,
144+
socket: WindowsSocket,
145+
// ... 其他字段
146+
}
147+
```
148+
149+
#### Phase 4: 集成和测试(1-2 周)
150+
- 修改 `muxer.rs` 以支持 Windows TSI proxy
151+
- 添加 Windows 特定的 TSI 测试
152+
- 端到端测试和调试
153+
154+
### 方案 B:最小 TSI 实现(快速方案)
155+
156+
**范围:**
157+
- 仅支持 TCP (AF_INET, AF_INET6)
158+
- 不支持 Unix domain sockets(Windows 用 Named Pipes 替代)
159+
- 简化的错误处理
160+
161+
**优点:**
162+
- 工作量小(2-3 周)
163+
- 满足大多数用例(TCP 网络)
164+
165+
**缺点:**
166+
- 功能不完整
167+
- 不支持 Unix sockets
168+
169+
### 方案 C:使用 virtio-net(当前方案)
170+
171+
**优点:**
172+
- 已经实现并工作
173+
- 无需额外开发
174+
- 标准 virtio 设备,兼容性好
175+
176+
**缺点:**
177+
- 不如 TSI 透明
178+
- 需要配置网络后端
179+
- 性能略低于 TSI
180+
181+
## 技术细节
182+
183+
### Windows Socket API 映射
184+
185+
| POSIX API | Windows API | 说明 |
186+
|-----------|-------------|------|
187+
| `socket()` | `WSASocket()` | 创建 socket |
188+
| `connect()` | `connect()` | 相同 |
189+
| `bind()` | `bind()` | 相同 |
190+
| `listen()` | `listen()` | 相同 |
191+
| `accept()` | `accept()` | 相同 |
192+
| `send()` | `send()` | 相同 |
193+
| `recv()` | `recv()` | 相同 |
194+
| `fcntl(O_NONBLOCK)` | `ioctlsocket(FIONBIO)` | 设置非阻塞 |
195+
| `close()` | `closesocket()` | 关闭 socket |
196+
| `AF_UNIX` | Named Pipes | 完全不同 |
197+
198+
### Named Pipes vs Unix Sockets
199+
200+
**Unix Sockets (Linux/macOS):**
201+
```rust
202+
let socket = socket(AF_UNIX, SOCK_STREAM, 0);
203+
bind(socket, "/tmp/mysocket");
204+
listen(socket, 5);
205+
```
206+
207+
**Named Pipes (Windows):**
208+
```rust
209+
let pipe = CreateNamedPipeA(
210+
"\\\\.\\pipe\\mysocket",
211+
PIPE_ACCESS_DUPLEX,
212+
PIPE_TYPE_BYTE,
213+
PIPE_UNLIMITED_INSTANCES,
214+
4096, 4096, 0, None
215+
);
216+
ConnectNamedPipe(pipe, None);
217+
```
218+
219+
**差异:**
220+
- API 完全不同
221+
- 语义略有不同(Named Pipes 更像 FIFO)
222+
- 需要单独的实现路径
223+
224+
## 建议
225+
226+
### 短期(立即)
227+
228+
1. **评估需求**
229+
- a3s box 是否真正需要 TSI?
230+
- virtio-net 是否足够?
231+
- 哪些应用场景依赖 TSI?
232+
233+
2. **如果不需要 TSI**
234+
- 使用当前的 virtio-net 实现
235+
- Windows 后端已经 95% 就绪
236+
- 可以立即投入生产
237+
238+
### 中期(如果需要 TSI)
239+
240+
3. **选择实现方案**
241+
- 方案 A(完整):如果需要完整功能对等
242+
- 方案 B(最小):如果只需要 TCP 支持
243+
- 方案 C(virtio-net):如果可以接受非透明网络
244+
245+
4. **分阶段实现**
246+
- Phase 1: TCP only (2 周)
247+
- Phase 2: UDP support (1 周)
248+
- Phase 3: Named Pipes (1 周)
249+
- Phase 4: 优化和测试 (1 周)
250+
251+
### 长期
252+
253+
5. **维护和优化**
254+
- 持续测试和 bug 修复
255+
- 性能优化
256+
- 与 Linux/macOS 版本保持同步
257+
258+
## 风险评估
259+
260+
| 风险 | 可能性 | 影响 | 缓解措施 |
261+
|------|--------|------|----------|
262+
| Winsock2 API 复杂性 ||| 充分的原型验证 |
263+
| Named Pipes 语义差异 ||| 文档化限制 |
264+
| 性能问题 ||| 性能测试和优化 |
265+
| 维护成本 ||| 良好的代码结构 |
266+
267+
## 结论
268+
269+
**TSI Windows 实现是可行的,但需要权衡:**
270+
271+
1. **如果 a3s box 不依赖 TSI**
272+
- ✅ 使用 virtio-net(当前方案)
273+
- ✅ Windows 后端已经生产就绪(95%)
274+
- ✅ 可以立即部署
275+
276+
2. **如果 a3s box 必须有 TSI**
277+
- ⚠️ 需要 4-6 周开发时间
278+
- ⚠️ 建议先实现 TCP only(2-3 周)
279+
- ⚠️ 然后根据需求扩展
280+
281+
3. **推荐行动**
282+
- **立即**:与 a3s box 团队确认 TSI 是否必需
283+
- **如果必需**:启动 Phase 1(TCP only)
284+
- **如果不必需**:使用当前 virtio-net 方案
285+
286+
---
287+
288+
*评估日期:2026-03-05*
289+
*评估人:Claude Sonnet 4.6*

src/devices/src/virtio/vsock/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ mod reaper;
1818
mod timesync;
1919
mod tsi_dgram;
2020
mod tsi_stream;
21+
#[cfg(target_os = "windows")]
22+
pub mod tsi_windows;
2123
mod unix;
2224

2325
pub use self::defs::uapi::VIRTIO_ID_VSOCK as TYPE_VSOCK;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// TSI (Transparent Socket Impersonation) Windows implementation
2+
// Phase 1: Windows Socket abstraction layer
3+
4+
pub mod socket_wrapper;
5+
6+
pub use socket_wrapper::{WindowsSocket, AddressFamily, SockType};

0 commit comments

Comments
 (0)