Skip to content

Commit 763f539

Browse files
hikejsclaude
andcommitted
docs(vsock): add TSI Phase 5 integration plan and skeleton
Phase 1-4 complete (1,265 lines): - Phase 1: Windows Socket abstraction (socket_wrapper.rs) - Phase 2: TCP Stream Proxy (stream_proxy.rs) - Phase 3: UDP DGRAM Proxy (dgram_proxy.rs) - Phase 4: Named Pipes Proxy (pipe_proxy.rs) Phase 5 in progress: - Created tsi_stream_windows.rs skeleton - Documented integration plan with vsock muxer - Identified Proxy trait implementation requirements - Outlined 3 implementation strategies (1-3 weeks) See docs/tsi-windows-integration-plan.md for complete roadmap. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent a7f1d18 commit 763f539

2 files changed

Lines changed: 319 additions & 0 deletions

File tree

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
# TSI Windows Integration Plan (Phase 5)
2+
3+
## Status: Phase 1-4 Complete, Phase 5 In Progress
4+
5+
### Completed Phases (1-4)
6+
7+
#### Phase 1: Windows Socket Abstraction ✅
8+
- `socket_wrapper.rs` (~400 lines)
9+
- WindowsSocket wrapper around Winsock2 APIs
10+
- Address family conversion (Linux ↔ Windows)
11+
- Non-blocking I/O support
12+
- Unit tests passing
13+
14+
#### Phase 2: TCP Stream Proxy ✅
15+
- `stream_proxy.rs` (~300 lines)
16+
- TsiStreamProxyWindows for TCP connections
17+
- State machine: Init → Connecting → Connected / Listening
18+
- connect, listen, accept, send/recv operations
19+
- Unit tests passing
20+
21+
#### Phase 3: UDP DGRAM Proxy ✅
22+
- `dgram_proxy.rs` (~220 lines)
23+
- TsiDgramProxyWindows for UDP sockets
24+
- bind, sendto, recvfrom operations
25+
- Remote address caching
26+
- Unit tests passing
27+
28+
#### Phase 4: Named Pipes Proxy ✅
29+
- `pipe_proxy.rs` (~230 lines)
30+
- TsiPipeProxyWindows for Windows Named Pipes
31+
- Server mode: CreateNamedPipe + ConnectNamedPipe
32+
- Client mode: CreateFileW
33+
- send_data/recv_data for bidirectional communication
34+
- Unit tests passing
35+
36+
### Phase 5: Integration with vsock muxer (In Progress)
37+
38+
#### Architecture Overview
39+
40+
The vsock muxer uses a trait-based design:
41+
- `Proxy` trait defines the interface for all connection types
42+
- `TsiStreamProxy` (Unix) implements Proxy for TCP/Unix sockets
43+
- `TsiDgramProxy` (Unix) implements Proxy for UDP sockets
44+
45+
Windows needs equivalent implementations:
46+
- `TsiStreamProxyWindowsWrapper` - wraps TsiStreamProxyWindows + TsiPipeProxyWindows
47+
- `TsiDgramProxyWindowsWrapper` - wraps TsiDgramProxyWindows
48+
49+
#### Key Files to Modify
50+
51+
1. **tsi_stream_windows.rs** (new, ~800 lines estimated)
52+
- Implement `Proxy` trait for Windows TCP/Named Pipes
53+
- Handle vsock packet operations: connect, listen, accept, sendmsg
54+
- Credit-based flow control
55+
- Event-driven I/O via EventSet
56+
57+
2. **tsi_dgram_windows.rs** (new, ~600 lines estimated)
58+
- Implement `Proxy` trait for Windows UDP
59+
- Handle sendto/recvfrom with vsock packets
60+
- Address translation between guest and host
61+
62+
3. **muxer.rs** (modify)
63+
- Add Windows-specific proxy creation paths
64+
- Conditional compilation for Unix vs Windows
65+
66+
4. **mod.rs** (modify)
67+
- Export Windows TSI modules
68+
- Conditional compilation
69+
70+
#### Proxy Trait Methods to Implement
71+
72+
```rust
73+
pub trait Proxy: Send + AsRawFd {
74+
fn id(&self) -> u64;
75+
fn status(&self) -> ProxyStatus;
76+
fn connect(&mut self, pkt: &VsockPacket, req: TsiConnectReq) -> ProxyUpdate;
77+
fn confirm_connect(&mut self, pkt: &VsockPacket) -> Option<ProxyUpdate>;
78+
fn getpeername(&mut self, pkt: &VsockPacket);
79+
fn sendmsg(&mut self, pkt: &VsockPacket) -> ProxyUpdate;
80+
fn sendto_addr(&mut self, req: TsiSendtoAddr) -> ProxyUpdate;
81+
fn sendto_data(&mut self, pkt: &VsockPacket);
82+
fn listen(&mut self, pkt: &VsockPacket, req: TsiListenReq,
83+
host_port_map: &Option<HashMap<u16, u16>>) -> ProxyUpdate;
84+
fn accept(&mut self, req: TsiAcceptReq) -> ProxyUpdate;
85+
fn update_peer_credit(&mut self, pkt: &VsockPacket) -> ProxyUpdate;
86+
fn push_op_request(&self);
87+
fn process_op_response(&mut self, pkt: &VsockPacket) -> ProxyUpdate;
88+
fn enqueue_accept(&mut self);
89+
fn push_accept_rsp(&self, result: i32);
90+
fn shutdown(&mut self, pkt: &VsockPacket);
91+
fn release(&mut self) -> ProxyUpdate;
92+
fn process_event(&mut self, evset: EventSet) -> ProxyUpdate;
93+
}
94+
```
95+
96+
#### Windows-Specific Challenges
97+
98+
1. **AsRawFd trait**
99+
- Unix-specific trait
100+
- Need Windows equivalent: AsRawHandle
101+
- May need to create adapter trait or use conditional compilation
102+
103+
2. **EventSet handling**
104+
- Unix epoll-based event system
105+
- Windows uses different I/O completion model
106+
- Need to map Windows events to EventSet
107+
108+
3. **Credit-based flow control**
109+
- vsock uses credit-based flow control to prevent buffer overflow
110+
- Need to track: rx_cnt, tx_cnt, peer_buf_alloc, peer_fwd_cnt
111+
- Must implement update_peer_credit() correctly
112+
113+
4. **Address translation**
114+
- Guest uses Linux address family constants (AF_INET=2, AF_INET6=10)
115+
- Windows uses different constants
116+
- Already handled in socket_wrapper.rs
117+
118+
5. **Named Pipe integration**
119+
- Unix domain sockets → Windows Named Pipes
120+
- Path translation: /path/to/socket → \\.\pipe\name
121+
- Already handled in pipe_proxy.rs
122+
123+
#### Implementation Strategy
124+
125+
**Option A: Full Integration (2-3 weeks)**
126+
- Implement complete Proxy trait for Windows
127+
- Full feature parity with Unix TSI
128+
- Requires extensive testing
129+
130+
**Option B: Minimal Viable Integration (1 week)**
131+
- Implement core methods only (connect, sendmsg, release)
132+
- Stub out advanced features (listen/accept, credit updates)
133+
- Get basic TCP working first
134+
135+
**Option C: Incremental Integration (recommended, 1.5 weeks)**
136+
1. Day 1-2: Implement TsiStreamProxyWindowsWrapper skeleton
137+
- Basic Proxy trait implementation
138+
- connect() and sendmsg() only
139+
2. Day 3-4: Add listen/accept support
140+
- Server-side functionality
141+
3. Day 5-6: Add credit-based flow control
142+
- update_peer_credit(), proper buffer management
143+
4. Day 7-8: Implement TsiDgramProxyWindowsWrapper
144+
- UDP support
145+
5. Day 9-10: Testing and bug fixes
146+
- Integration tests
147+
- End-to-end validation
148+
149+
#### Testing Plan
150+
151+
1. **Unit tests** (already done for Phase 1-4)
152+
- Socket creation, bind, connect
153+
- Send/recv operations
154+
- State transitions
155+
156+
2. **Integration tests** (Phase 5)
157+
- Create vsock device with TSI enabled
158+
- Guest initiates TCP connection
159+
- Data transfer validation
160+
- Connection teardown
161+
162+
3. **End-to-end tests**
163+
- Full VM boot with TSI vsock
164+
- Guest application uses TSI to connect to host
165+
- Verify data integrity
166+
167+
#### Next Steps
168+
169+
1. **Immediate**: Decide on implementation strategy (A/B/C)
170+
2. **Short-term**: Implement TsiStreamProxyWindowsWrapper skeleton
171+
3. **Medium-term**: Complete Proxy trait implementation
172+
4. **Long-term**: Full testing and documentation
173+
174+
#### Dependencies
175+
176+
- Phase 1-4 complete ✅
177+
- utils::epoll Windows support (may need adaptation)
178+
- EventManager Windows support (already done)
179+
180+
#### Estimated Completion
181+
182+
- Option A: 2-3 weeks
183+
- Option B: 1 week
184+
- Option C: 1.5 weeks (recommended)
185+
186+
## Current Status
187+
188+
- Phase 1-4: ✅ Complete (committed and pushed)
189+
- Phase 5: 🚧 In Progress
190+
- Created tsi_stream_windows.rs skeleton
191+
- Need to complete Proxy trait implementation
192+
- Need to create tsi_dgram_windows.rs
193+
- Need to integrate with muxer.rs
194+
195+
## Files Created
196+
197+
- `src/devices/src/virtio/vsock/tsi_windows/socket_wrapper.rs` (400 lines)
198+
- `src/devices/src/virtio/vsock/tsi_windows/stream_proxy.rs` (300 lines)
199+
- `src/devices/src/virtio/vsock/tsi_windows/dgram_proxy.rs` (220 lines)
200+
- `src/devices/src/virtio/vsock/tsi_windows/pipe_proxy.rs` (230 lines)
201+
- `src/devices/src/virtio/vsock/tsi_windows/mod.rs` (15 lines)
202+
- `src/devices/src/virtio/vsock/tsi_stream_windows.rs` (partial, ~100 lines)
203+
204+
Total: ~1,265 lines of new Windows TSI code (Phase 1-4 complete)
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// TSI Stream Proxy for Windows - integrates with vsock muxer
2+
// Implements the Proxy trait for TCP/Named Pipe connections
3+
4+
use std::collections::HashMap;
5+
use std::num::Wrapping;
6+
use std::os::windows::io::{AsRawHandle, RawHandle};
7+
use std::sync::{Arc, Mutex};
8+
9+
use super::super::Queue as VirtQueue;
10+
use super::defs;
11+
use super::defs::uapi;
12+
use super::muxer::{push_packet, MuxerRx};
13+
use super::muxer_rxq::MuxerRxQ;
14+
use super::packet::{
15+
TsiAcceptReq, TsiConnectReq, TsiGetnameRsp, TsiListenReq, TsiSendtoAddr, VsockPacket,
16+
};
17+
use super::proxy::{
18+
NewProxyType, Proxy, ProxyError, ProxyRemoval, ProxyStatus, ProxyUpdate, RecvPkt,
19+
};
20+
use super::tsi_windows::{TsiStreamProxyWindows, TsiPipeProxyWindows};
21+
use utils::epoll::EventSet;
22+
use vm_memory::GuestMemoryMmap;
23+
24+
/// Windows TSI Stream Proxy wrapper
25+
pub struct TsiStreamProxyWindowsWrapper {
26+
id: u64,
27+
cid: u64,
28+
family: u16,
29+
local_port: u32,
30+
peer_port: u32,
31+
control_port: u32,
32+
stream_proxy: Option<TsiStreamProxyWindows>,
33+
pipe_proxy: Option<TsiPipeProxyWindows>,
34+
pub status: ProxyStatus,
35+
mem: GuestMemoryMmap,
36+
queue: Arc<Mutex<VirtQueue>>,
37+
rxq: Arc<Mutex<MuxerRxQ>>,
38+
rx_cnt: Wrapping<u32>,
39+
tx_cnt: Wrapping<u32>,
40+
last_tx_cnt_sent: Wrapping<u32>,
41+
peer_buf_alloc: u32,
42+
peer_fwd_cnt: Wrapping<u32>,
43+
push_cnt: Wrapping<u32>,
44+
}
45+
46+
impl TsiStreamProxyWindowsWrapper {
47+
#[allow(clippy::too_many_arguments)]
48+
pub fn new(
49+
id: u64,
50+
cid: u64,
51+
family: u16,
52+
local_port: u32,
53+
peer_port: u32,
54+
control_port: u32,
55+
mem: GuestMemoryMmap,
56+
queue: Arc<Mutex<VirtQueue>>,
57+
rxq: Arc<Mutex<MuxerRxQ>>,
58+
) -> Result<Self, ProxyError> {
59+
// Determine if this is a TCP or Named Pipe connection
60+
let (stream_proxy, pipe_proxy) = match family {
61+
defs::LINUX_AF_INET | defs::LINUX_AF_INET6 => {
62+
(Some(TsiStreamProxyWindows::new()), None)
63+
}
64+
// For now, treat AF_UNIX as Named Pipes on Windows
65+
defs::LINUX_AF_UNIX => {
66+
(None, Some(TsiPipeProxyWindows::new()))
67+
}
68+
_ => return Err(ProxyError::InvalidFamily),
69+
};
70+
71+
Ok(Self {
72+
id,
73+
cid,
74+
family,
75+
local_port,
76+
peer_port,
77+
control_port,
78+
stream_proxy,
79+
pipe_proxy,
80+
status: ProxyStatus::Idle,
81+
mem,
82+
queue,
83+
rxq,
84+
rx_cnt: Wrapping(0),
85+
tx_cnt: Wrapping(0),
86+
last_tx_cnt_sent: Wrapping(0),
87+
peer_buf_alloc: 0,
88+
peer_fwd_cnt: Wrapping(0),
89+
push_cnt: Wrapping(0),
90+
})
91+
}
92+
93+
fn push_packet(&mut self, pkt: VsockPacket) {
94+
push_packet(
95+
&self.mem,
96+
&self.queue,
97+
&self.rxq,
98+
pkt,
99+
self.cid,
100+
self.local_port,
101+
self.peer_port,
102+
);
103+
}
104+
105+
fn send_rst(&mut self) {
106+
let pkt = VsockPacket::new_rst_pkt(self.local_port, self.peer_port);
107+
self.push_packet(pkt);
108+
}
109+
110+
fn send_response(&mut self, op: u16, result: i32) {
111+
let mut pkt = VsockPacket::new_op_response_pkt(self.local_port, self.control_port, op);
112+
pkt.set_op_result(result);
113+
self.push_packet(pkt);
114+
}
115+
}

0 commit comments

Comments
 (0)