snowstorm/config/
serializable.rs

1use libp2p::Multiaddr;
2use libp2p::PeerId;
3use libp2p::{identity::Keypair, multiaddr};
4use serde::{Deserialize, Serialize};
5use std::{collections::HashSet, str::FromStr};
6
7use super::{AddrInfo, Config, Hop, RouteDescriptor};
8use crate::identity::Role;
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct SerializableAddrInfo {
12    #[serde(rename = "PeerID")]
13    pub peer_id: String,
14    #[serde(rename = "Multiaddrs")]
15    pub multiaddrs: Vec<String>,
16}
17
18impl From<AddrInfo> for SerializableAddrInfo {
19    fn from(value: AddrInfo) -> Self {
20        Self {
21            peer_id: value.peer_id.to_base58(),
22            multiaddrs: value
23                .multiaddrs
24                .into_iter()
25                .map(|m| m.to_string())
26                .collect(),
27        }
28    }
29}
30
31impl TryFrom<SerializableAddrInfo> for AddrInfo {
32    type Error = multiaddr::Error;
33
34    fn try_from(value: SerializableAddrInfo) -> Result<Self, Self::Error> {
35        let mut multiaddrs = Vec::with_capacity(value.multiaddrs.len());
36
37        for m in value.multiaddrs {
38            multiaddrs.push(m.parse()?);
39        }
40
41        Ok(Self {
42            peer_id: value
43                .peer_id
44                .parse()
45                .map_err(|_| multiaddr::Error::InvalidMultiaddr)?,
46            multiaddrs,
47        })
48    }
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct SerializableHop {
53    #[serde(rename = "AddrInfo")]
54    pub addr_info: Vec<SerializableAddrInfo>,
55    #[serde(rename = "Policy")]
56    pub policy: String,
57    #[serde(rename = "User", default)]
58    pub user: String,
59}
60
61impl From<SerializableHop> for Hop {
62    fn from(value: SerializableHop) -> Self {
63        Self {
64            addr_info: value
65                .addr_info
66                .into_iter()
67                .map(|a| a.try_into().ok())
68                .collect::<Option<Vec<AddrInfo>>>()
69                .unwrap_or_default(),
70            policy: value.policy,
71            user: value.user,
72        }
73    }
74}
75
76impl From<Hop> for SerializableHop {
77    fn from(value: Hop) -> Self {
78        Self {
79            addr_info: value.addr_info.into_iter().map(|a| a.into()).collect(),
80            policy: value.policy,
81            user: value.user,
82        }
83    }
84}
85
86#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct SerializableRouteDescriptor {
88    #[serde(rename = "ID")]
89    pub id: String,
90
91    #[serde(rename = "Name")]
92    pub name: String,
93
94    #[serde(rename = "Path")]
95    pub path: Vec<SerializableHop>,
96
97    #[serde(rename = "TTL")]
98    pub ttl: i32,
99
100    #[serde(rename = "Reference", default)]
101    pub reference: Option<u32>,
102}
103
104impl From<RouteDescriptor> for SerializableRouteDescriptor {
105    fn from(value: RouteDescriptor) -> Self {
106        Self {
107            id: value.id.clone(),
108            name: value.name.clone(),
109            path: value.path.into_iter().map(|p| p.into()).collect(),
110            ttl: value.ttl,
111            reference: value.reference,
112        }
113    }
114}
115
116impl TryFrom<SerializableRouteDescriptor> for RouteDescriptor {
117    type Error = multiaddr::Error;
118
119    fn try_from(value: SerializableRouteDescriptor) -> Result<Self, Self::Error> {
120        let mut path = Vec::with_capacity(value.path.len());
121
122        for p in value.path {
123            path.push(p.into());
124        }
125
126        Ok(Self {
127            id: value.id,
128            name: value.name,
129            path,
130            ttl: value.ttl,
131            reference: value.reference,
132        })
133    }
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize)]
137pub struct SerializableConfig {
138    pub privacy_level: isize,
139    pub location: Option<String>,
140    pub roles: HashSet<Role>,
141    pub keypair: Vec<u8>,
142    pub entry_peers: Vec<String>,
143    pub listen_on: Vec<String>,
144    pub namespace: String,
145    pub discovery_ttl: Option<u64>,
146    /// deprecated
147    pub static_exits: Vec<String>,
148    #[serde(default)]
149    pub static_routes: Vec<SerializableRouteDescriptor>,
150    pub sserver_listen_addr: String,
151    pub sclient_listen_addr: String,
152    pub fdlimit: bool,
153    pub external_addrs: Vec<String>,
154    pub token: Option<String>,
155    #[serde(default)]
156    pub device_id: Option<String>,
157    #[serde(default)]
158    pub route_auth_enabled: bool,
159}
160
161impl From<Config> for SerializableConfig {
162    fn from(config: Config) -> Self {
163        let entry_peers: Vec<String> = config
164            .entry_peers
165            .into_iter()
166            .map(|addr| Multiaddr::to_string(&addr))
167            .collect();
168
169        let listen_on: Vec<String> = config
170            .listen_on
171            .into_iter()
172            .map(|addr| Multiaddr::to_string(&addr))
173            .collect();
174
175        let external_addrs: Vec<String> = config
176            .external_addrs
177            .into_iter()
178            .map(|addr| Multiaddr::to_string(&addr))
179            .collect();
180
181        let static_exits: Vec<String> = config
182            .static_exits
183            .into_iter()
184            .map(|addr| Multiaddr::to_string(&addr))
185            .collect();
186
187        SerializableConfig {
188            privacy_level: config.privacy_level,
189            location: config.location,
190            roles: config.roles,
191            keypair: config.keypair.to_protobuf_encoding().unwrap(),
192            entry_peers,
193            listen_on,
194            namespace: config.namespace,
195            discovery_ttl: config.discovery_ttl,
196            static_exits,
197            static_routes: config.static_routes.into_iter().map(|r| r.into()).collect(),
198            sserver_listen_addr: config.sserver_listen_addr,
199            sclient_listen_addr: config.sclient_listen_addr,
200            fdlimit: config.fdlimit,
201            external_addrs,
202            token: config.token,
203            device_id: config.device_id,
204            route_auth_enabled: config.route_auth_enabled,
205        }
206    }
207}
208
209impl From<SerializableConfig> for Config {
210    fn from(config: SerializableConfig) -> Self {
211        let entry_peers: Vec<Multiaddr> = config
212            .entry_peers
213            .into_iter()
214            .map(|addr| Multiaddr::from_str(&addr).unwrap())
215            .collect();
216
217        let listen_on: Vec<Multiaddr> = config
218            .listen_on
219            .into_iter()
220            .map(|addr| Multiaddr::from_str(&addr).unwrap())
221            .collect();
222
223        let external_addrs: Vec<Multiaddr> = config
224            .external_addrs
225            .into_iter()
226            .map(|addr| Multiaddr::from_str(&addr).unwrap())
227            .collect();
228
229        let static_exits: Vec<Multiaddr> = config
230            .static_exits
231            .into_iter()
232            .map(|addr| Multiaddr::from_str(&addr).unwrap())
233            .collect();
234
235        let mut static_routes: Vec<RouteDescriptor> = config
236            .static_routes
237            .into_iter()
238            .map(|r| r.try_into().unwrap())
239            .collect();
240
241        if static_routes.is_empty() {
242            for exit in static_exits.clone() {
243                let peer_id = match exit.iter().last() {
244                    Some(multiaddr::Protocol::P2p(peer_id)) => peer_id,
245                    _ => continue,
246                };
247
248                let addr_info = AddrInfo {
249                    peer_id,
250                    multiaddrs: vec![exit.clone()],
251                };
252
253                let hop = Hop {
254                    addr_info: vec![addr_info],
255                    policy: "".to_owned(),
256                    user: "".to_owned(),
257                };
258
259                static_routes.push(RouteDescriptor {
260                    id: "".to_owned(),
261                    name: "".to_owned(),
262                    path: vec![hop],
263                    ttl: 0,
264                    reference: None,
265                });
266            }
267        }
268
269        Config {
270            privacy_level: config.privacy_level,
271            location: config.location,
272            roles: config.roles,
273            keypair: Keypair::from_protobuf_encoding(&config.keypair).unwrap(),
274            entry_peers,
275            listen_on,
276            namespace: config.namespace,
277            discovery_ttl: config.discovery_ttl,
278            static_exits,
279            static_routes,
280            sserver_listen_addr: config.sserver_listen_addr,
281            sclient_listen_addr: config.sclient_listen_addr,
282            fdlimit: config.fdlimit,
283            external_addrs,
284            // Do not serialize these, either not app related or explicitly set.
285            outbound_addrs: Vec::new(),
286            is_fly_io: false,
287            protect_socket_fn: None,
288            token: config.token,
289            device_id: config.device_id,
290            route_auth_enabled: config.route_auth_enabled,
291        }
292    }
293}
294
295#[derive(Serialize, Deserialize, Debug, Clone)]
296pub struct GeoIp {
297    pub ip: String,
298    #[serde(rename = "geoip")]
299    pub geo_ip: Option<GeoIpDetails>,
300    #[serde(default)]
301    pub active: bool,
302}
303
304#[derive(Serialize, Deserialize, Debug, Clone)]
305pub struct GeoIpDetails {
306    pub country: String,
307    pub city: String,
308    pub lat: f64,
309    pub lon: f64,
310}
311
312#[derive(Debug, Clone, Serialize, Deserialize)]
313pub struct Device {
314    #[serde(rename = "Id")]
315    pub id: String,
316
317    #[serde(rename = "Name")]
318    pub name: String,
319
320    #[serde(rename = "Type")]
321    pub device_type: String,
322
323    #[serde(rename = "PeerID")]
324    pub peer_id: PeerId,
325
326    #[serde(rename = "Updated")]
327    pub updated: String,
328}
329
330#[derive(Debug, Clone, Serialize, Deserialize)]
331pub struct ProfilePeer {
332    #[serde(rename = "PeerID")]
333    pub peer_id: PeerId,
334
335    #[serde(rename = "Multiaddrs")]
336    pub multiaddrs: Vec<String>,
337
338    #[serde(rename = "Updated")]
339    pub updated: String,
340}
341
342#[derive(Debug, Clone, Serialize, Deserialize)]
343pub struct Profile {
344    pub devices: Option<Vec<Device>>,
345    pub state: String,
346    pub header: String,
347    pub peers: Option<Vec<ProfilePeer>>,
348}