Skip to main content

vox_types/
handshake.rs

1use facet::Facet;
2
3use crate::{ConnectionSettings, Metadata, Parity, Schema, SessionResumeKey};
4
5// r[impl session.handshake]
6// r[impl session.handshake.cbor]
7/// CBOR-encoded handshake message exchanged before postcard traffic begins.
8#[derive(Debug, Clone, Facet)]
9#[repr(u8)]
10pub enum HandshakeMessage {
11    Hello(Hello),
12    HelloYourself(HelloYourself),
13    LetsGo(LetsGo),
14    Sorry(Sorry),
15}
16
17// r[impl session.handshake]
18/// Sent by the initiator as the first handshake message.
19#[derive(Debug, Clone, Facet)]
20pub struct Hello {
21    /// The identifier partition desired by the initiator.
22    pub parity: Parity,
23    /// Connection limits advertised by the initiator for the root connection.
24    pub connection_settings: ConnectionSettings,
25    // r[impl session.handshake.protocol-schema]
26    /// The initiator's schema for MessagePayload — the postcard enum used
27    /// for all subsequent communication.
28    pub message_payload_schema: Vec<Schema>,
29    /// Whether the initiator supports operation-level retry.
30    #[facet(default)]
31    pub supports_retry: bool,
32    /// Session resume key (present only when resuming an existing session).
33    #[facet(default)]
34    pub resume_key: Option<ResumeKeyBytes>,
35    /// Metadata sent by the initiator (e.g. `vox-service` for service routing).
36    #[facet(default)]
37    pub metadata: Metadata<'static>,
38}
39
40// r[impl session.handshake]
41/// Sent by the acceptor in response to Hello.
42#[derive(Debug, Clone, Facet)]
43pub struct HelloYourself {
44    /// Connection limits advertised by the acceptor for the root connection.
45    pub connection_settings: ConnectionSettings,
46    // r[impl session.handshake.protocol-schema]
47    /// The acceptor's schema for MessagePayload.
48    pub message_payload_schema: Vec<Schema>,
49    /// Whether the acceptor supports operation-level retry.
50    #[facet(default)]
51    pub supports_retry: bool,
52    /// Session resume key (generated by acceptor for future resumption).
53    #[facet(default)]
54    pub resume_key: Option<ResumeKeyBytes>,
55    /// Metadata sent by the acceptor.
56    #[facet(default)]
57    pub metadata: Metadata<'static>,
58}
59
60// r[impl session.handshake]
61/// Sent by the initiator to confirm schema compatibility and establish the session.
62#[derive(Debug, Clone, Facet)]
63pub struct LetsGo {}
64
65// r[impl session.handshake.sorry]
66/// Sent by either peer to reject the session due to schema incompatibility.
67#[derive(Debug, Clone, Facet)]
68pub struct Sorry {
69    pub reason: String,
70}
71
72/// Fixed-size resume key bytes, CBOR-serializable.
73#[derive(Debug, Clone, Facet)]
74pub struct ResumeKeyBytes {
75    pub bytes: Vec<u8>,
76}
77
78impl ResumeKeyBytes {
79    pub fn from_key(key: &SessionResumeKey) -> Self {
80        Self {
81            bytes: key.0.to_vec(),
82        }
83    }
84
85    pub fn to_key(&self) -> Option<SessionResumeKey> {
86        if self.bytes.len() == 16 {
87            let mut arr = [0u8; 16];
88            arr.copy_from_slice(&self.bytes);
89            Some(SessionResumeKey(arr))
90        } else {
91            None
92        }
93    }
94}
95
96/// Result of a completed CBOR handshake.
97#[derive(Debug, Clone)]
98pub struct HandshakeResult {
99    pub role: crate::SessionRole,
100    pub our_settings: ConnectionSettings,
101    pub peer_settings: ConnectionSettings,
102    pub peer_supports_retry: bool,
103    /// The resume key for this session. For the acceptor, this is the key
104    /// we generated and sent in HelloYourself. For the initiator, this is
105    /// the key the acceptor sent us.
106    pub session_resume_key: Option<SessionResumeKey>,
107    /// The resume key the peer sent in their Hello (initiator→acceptor only).
108    /// Used by the acceptor to look up existing sessions for resumption.
109    pub peer_resume_key: Option<SessionResumeKey>,
110    pub our_schema: Vec<Schema>,
111    pub peer_schema: Vec<Schema>,
112    /// Metadata received from the peer during handshake.
113    pub peer_metadata: Metadata<'static>,
114}