Skip to main content

microsandbox_protocol/
tcp.rs

1//! TCP stream protocol message payloads.
2
3use serde::{Deserialize, Serialize};
4
5//--------------------------------------------------------------------------------------------------
6// Types
7//--------------------------------------------------------------------------------------------------
8
9/// Request to open a TCP connection from inside the guest.
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct TcpConnect {
12    /// Destination host name or address as seen by the guest.
13    pub host: String,
14
15    /// Destination TCP port.
16    pub port: u16,
17}
18
19/// Confirmation that a TCP connection was opened.
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct TcpConnected {}
22
23/// TCP stream data.
24#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct TcpData {
26    /// The raw stream bytes.
27    #[serde(with = "serde_bytes")]
28    pub data: Vec<u8>,
29}
30
31/// Notification that one side has closed its write half.
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct TcpEof {}
34
35/// Request to close the TCP session.
36#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct TcpClose {}
38
39/// Terminal notification that the TCP session is closed.
40#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct TcpClosed {}
42
43/// Terminal notification that the TCP session failed.
44#[derive(Debug, Clone, Serialize, Deserialize)]
45pub struct TcpFailed {
46    /// Human-readable failure description.
47    pub error: String,
48}
49
50//--------------------------------------------------------------------------------------------------
51// Tests
52//--------------------------------------------------------------------------------------------------
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn tcp_payloads_roundtrip() {
60        let connect = TcpConnect {
61            host: "127.0.0.1".to_string(),
62            port: 8080,
63        };
64        let mut buf = Vec::new();
65        ciborium::into_writer(&connect, &mut buf).unwrap();
66        let decoded: TcpConnect = ciborium::from_reader(&buf[..]).unwrap();
67        assert_eq!(decoded.host, connect.host);
68        assert_eq!(decoded.port, connect.port);
69
70        let data = TcpData {
71            data: b"hello".to_vec(),
72        };
73        buf.clear();
74        ciborium::into_writer(&data, &mut buf).unwrap();
75        let decoded: TcpData = ciborium::from_reader(&buf[..]).unwrap();
76        assert_eq!(decoded.data, data.data);
77
78        let failed = TcpFailed {
79            error: "connection refused".to_string(),
80        };
81        buf.clear();
82        ciborium::into_writer(&failed, &mut buf).unwrap();
83        let decoded: TcpFailed = ciborium::from_reader(&buf[..]).unwrap();
84        assert_eq!(decoded.error, failed.error);
85    }
86}