ng_net/actors/
start.rs

1/*
2 * Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
3 * All rights reserved.
4 * Licensed under the Apache License, Version 2.0
5 * <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
6 * or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
7 * at your option. All files in the project carrying such
8 * notice may not be copied, modified, or distributed except
9 * according to those terms.
10*/
11
12use std::any::{Any, TypeId};
13use std::sync::Arc;
14
15use async_std::sync::Mutex;
16use serde::{Deserialize, Serialize};
17
18use ng_repo::errors::*;
19use ng_repo::log::*;
20use ng_repo::types::UserId;
21
22use crate::actors::noise::Noise;
23use crate::connection::NoiseFSM;
24use crate::types::{
25    AdminRequest, ClientInfo, CoreBrokerConnect, CoreBrokerConnectResponse, CoreMessage,
26    CoreMessageV0, CoreResponse, CoreResponseContentV0, CoreResponseV0, ExtRequest,
27};
28use crate::{actor::*, types::ProtocolMessage};
29
30// pub struct Noise3(Noise);
31
32/// Start chosen protocol
33/// First message sent by the connecting peer
34#[derive(Clone, Debug, Serialize, Deserialize)]
35pub enum StartProtocol {
36    Client(ClientHello),
37    Ext(ExtRequest),
38    Core(CoreHello),
39    Admin(AdminRequest),
40    App(AppHello),
41    AppResponse(AppHelloResponse),
42}
43
44impl StartProtocol {
45    pub fn type_id(&self) -> TypeId {
46        match self {
47            StartProtocol::Client(a) => a.type_id(),
48            StartProtocol::Core(a) => a.type_id(),
49            StartProtocol::Ext(a) => a.type_id(),
50            StartProtocol::Admin(a) => a.type_id(),
51            StartProtocol::App(a) => a.type_id(),
52            StartProtocol::AppResponse(a) => a.type_id(),
53        }
54    }
55    pub fn get_actor(&self) -> Box<dyn EActor> {
56        match self {
57            StartProtocol::Client(a) => a.get_actor(),
58            StartProtocol::Core(a) => a.get_actor(),
59            StartProtocol::Ext(a) => a.get_actor(),
60            StartProtocol::Admin(a) => a.get_actor(),
61            StartProtocol::App(a) => a.get_actor(),
62            StartProtocol::AppResponse(_) => panic!("AppResponse is not a request"),
63        }
64    }
65}
66
67impl From<StartProtocol> for ProtocolMessage {
68    fn from(msg: StartProtocol) -> ProtocolMessage {
69        ProtocolMessage::Start(msg)
70    }
71}
72
73/// Core Hello (finalizes the Noise handshake and sends CoreConnect)
74#[derive(Clone, Debug, Serialize, Deserialize)]
75pub struct CoreHello {
76    // contains the 3rd Noise handshake message "s,se"
77    pub noise: Noise,
78
79    /// Noise encrypted payload (a CoreMessage::CoreRequest::BrokerConnect)
80    #[serde(with = "serde_bytes")]
81    pub payload: Vec<u8>,
82}
83
84impl CoreHello {
85    pub fn get_actor(&self) -> Box<dyn EActor> {
86        Actor::<CoreBrokerConnect, CoreBrokerConnectResponse>::new_responder(0)
87    }
88}
89
90impl TryFrom<ProtocolMessage> for CoreBrokerConnectResponse {
91    type Error = ProtocolError;
92    fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
93        if let ProtocolMessage::CoreMessage(CoreMessage::V0(CoreMessageV0::Response(
94            CoreResponse::V0(CoreResponseV0 {
95                content: CoreResponseContentV0::BrokerConnectResponse(a),
96                ..
97            }),
98        ))) = msg
99        {
100            Ok(a)
101        } else {
102            log_debug!("INVALID {:?}", msg);
103            Err(ProtocolError::InvalidValue)
104        }
105    }
106}
107
108impl From<CoreHello> for ProtocolMessage {
109    fn from(msg: CoreHello) -> ProtocolMessage {
110        ProtocolMessage::Start(StartProtocol::Core(msg))
111    }
112}
113
114impl From<CoreBrokerConnect> for ProtocolMessage {
115    fn from(_msg: CoreBrokerConnect) -> ProtocolMessage {
116        unimplemented!();
117    }
118}
119
120impl Actor<'_, CoreBrokerConnect, CoreBrokerConnectResponse> {}
121
122#[async_trait::async_trait]
123impl EActor for Actor<'_, CoreBrokerConnect, CoreBrokerConnectResponse> {
124    async fn respond(
125        &mut self,
126        _msg: ProtocolMessage,
127        _fsm: Arc<Mutex<NoiseFSM>>,
128    ) -> Result<(), ProtocolError> {
129        //let req = CoreBrokerConnect::try_from(msg)?;
130        // let res = CoreBrokerConnectResponse::V0(CoreBrokerConnectResponseV0 {
131        //     successes: vec![],
132        //     errors: vec![],
133        // });
134        // fsm.lock().await.send(res.into()).await?;
135        Ok(())
136    }
137}
138
139// /// External Hello (finalizes the Noise handshake and sends first ExtRequest)
140// #[derive(Clone, Debug, Serialize, Deserialize)]
141// pub struct ExtHello {
142//     // contains the 3rd Noise handshake message "s,se"
143//     pub noise: Noise,
144
145//     /// Noise encrypted payload (an ExtRequest)
146//     #[serde(with = "serde_bytes")]
147//     pub payload: Vec<u8>,
148// }
149
150// impl ExtHello {
151//     pub fn get_actor(&self) -> Box<dyn EActor> {
152//         Actor::<ExtHello, ExtResponse>::new_responder(0)
153//     }
154// }
155
156// impl From<ExtHello> for ProtocolMessage {
157//     fn from(msg: ExtHello) -> ProtocolMessage {
158//         ProtocolMessage::Start(StartProtocol::Ext(msg))
159//     }
160// }
161
162/// Client Hello
163#[derive(Clone, Debug, Serialize, Deserialize)]
164pub enum ClientHello {
165    // contains the 3rd Noise handshake message "s,se"
166    Noise3(Noise),
167    Local,
168}
169
170impl ClientHello {
171    pub fn type_id(&self) -> TypeId {
172        match self {
173            ClientHello::Noise3(a) => a.type_id(),
174            ClientHello::Local => TypeId::of::<ClientHello>(),
175        }
176    }
177    pub fn get_actor(&self) -> Box<dyn EActor> {
178        Actor::<ClientHello, ServerHello>::new_responder(0)
179    }
180}
181
182/// Server hello sent upon a client connection
183#[derive(Clone, Debug, Serialize, Deserialize)]
184pub struct ServerHelloV0 {
185    /// Nonce for ClientAuth
186    #[serde(with = "serde_bytes")]
187    pub nonce: Vec<u8>,
188}
189
190/// Server hello sent upon a client connection
191#[derive(Clone, Debug, Serialize, Deserialize)]
192pub enum ServerHello {
193    V0(ServerHelloV0),
194}
195
196impl ServerHello {
197    pub fn nonce(&self) -> &Vec<u8> {
198        match self {
199            ServerHello::V0(o) => &o.nonce,
200        }
201    }
202}
203
204impl From<ClientHello> for ProtocolMessage {
205    fn from(msg: ClientHello) -> ProtocolMessage {
206        ProtocolMessage::Start(StartProtocol::Client(msg))
207    }
208}
209
210impl TryFrom<ProtocolMessage> for ClientHello {
211    type Error = ProtocolError;
212    fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
213        if let ProtocolMessage::Start(StartProtocol::Client(a)) = msg {
214            Ok(a)
215        } else {
216            Err(ProtocolError::InvalidValue)
217        }
218    }
219}
220
221impl TryFrom<ProtocolMessage> for ServerHello {
222    type Error = ProtocolError;
223    fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
224        if let ProtocolMessage::ServerHello(server_hello) = msg {
225            Ok(server_hello)
226        } else {
227            Err(ProtocolError::InvalidValue)
228        }
229    }
230}
231
232impl From<ServerHello> for ProtocolMessage {
233    fn from(msg: ServerHello) -> ProtocolMessage {
234        ProtocolMessage::ServerHello(msg)
235    }
236}
237
238impl Actor<'_, ClientHello, ServerHello> {}
239
240#[async_trait::async_trait]
241impl EActor for Actor<'_, ClientHello, ServerHello> {
242    async fn respond(
243        &mut self,
244        msg: ProtocolMessage,
245        fsm: Arc<Mutex<NoiseFSM>>,
246    ) -> Result<(), ProtocolError> {
247        let _req = ClientHello::try_from(msg)?;
248        let res = ServerHello::V0(ServerHelloV0 { nonce: vec![] });
249        fsm.lock().await.send(res.into()).await?;
250        Ok(())
251    }
252}
253
254// impl Actor<'_, ExtHello, ExtResponse> {}
255
256// #[async_trait::async_trait]
257// impl EActor for Actor<'_, ExtHello, ExtResponse> {
258//     async fn respond(
259//         &mut self,
260//         _msg: ProtocolMessage,
261//         _fsm: Arc<Mutex<NoiseFSM>>,
262//     ) -> Result<(), ProtocolError> {
263//         Ok(())
264//     }
265// }
266
267// ///////////// APP HELLO ///////////////
268
269/// App Hello (finalizes the Noise handshake and sends info about device, and the user_id.
270/// not signing any nonce because anyway, in the next message "AppSessionRequest", the user_priv_key will be sent and checked again)
271#[derive(Clone, Debug, Serialize, Deserialize)]
272pub struct AppHello {
273    // contains the 3rd Noise handshake message "s,se"
274    pub noise: Noise,
275
276    pub user: Option<UserId>, // None for Headless
277
278    pub info: ClientInfo,
279}
280
281#[derive(Clone, Debug, Serialize, Deserialize)]
282pub struct AppHelloResponse {
283    pub result: u16,
284}
285
286impl AppHello {
287    pub fn get_actor(&self) -> Box<dyn EActor> {
288        Actor::<AppHello, AppHelloResponse>::new_responder(0)
289    }
290}
291
292impl From<AppHello> for ProtocolMessage {
293    fn from(msg: AppHello) -> ProtocolMessage {
294        ProtocolMessage::Start(StartProtocol::App(msg))
295    }
296}
297
298impl From<AppHelloResponse> for ProtocolMessage {
299    fn from(msg: AppHelloResponse) -> ProtocolMessage {
300        ProtocolMessage::Start(StartProtocol::AppResponse(msg))
301    }
302}
303
304impl TryFrom<ProtocolMessage> for AppHelloResponse {
305    type Error = ProtocolError;
306    fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
307        if let ProtocolMessage::Start(StartProtocol::AppResponse(res)) = msg {
308            Ok(res)
309        } else {
310            Err(ProtocolError::InvalidValue)
311        }
312    }
313}
314
315impl Actor<'_, AppHello, AppHelloResponse> {}
316
317#[async_trait::async_trait]
318impl EActor for Actor<'_, AppHello, AppHelloResponse> {
319    async fn respond(
320        &mut self,
321        _msg: ProtocolMessage,
322        _fsm: Arc<Mutex<NoiseFSM>>,
323    ) -> Result<(), ProtocolError> {
324        Ok(())
325    }
326}