narrowlink_types/
generic.rs1use core::fmt::Display;
2use hmac::Hmac;
3use serde::{Deserialize, Serialize};
4use sha3::Sha3_256;
5use std::{fmt::Debug, net::SocketAddr, str::FromStr};
6
7use crate::agent::{AgentPublishInfo, SystemInfo};
8
9pub type HmacSha256 = Hmac<Sha3_256>;
10
11#[derive(Serialize, Deserialize, Clone, Debug)]
12pub enum CryptographicAlgorithm {
13 XChaCha20Poly1305([u8; 24]), }
15#[derive(Serialize, Deserialize, Clone, Debug)]
16pub enum SigningAlgorithm {
17 HmacSha256([u8; 32]), }
19
20#[derive(Serialize, Deserialize, Clone)]
21pub struct Connect {
22 pub host: String,
23 pub port: u16,
24 pub protocol: Protocol,
25 pub cryptography: Option<CryptographicAlgorithm>,
26 pub sign: Option<SigningAlgorithm>,
27}
28impl Connect {
29 pub fn set_cryptography_nonce(&mut self, nonce: [u8; 24]) {
30 self.cryptography = Some(CryptographicAlgorithm::XChaCha20Poly1305(nonce));
31 }
32 pub fn get_cryptography_nonce(&self) -> Option<[u8; 24]> {
33 if let Some(CryptographicAlgorithm::XChaCha20Poly1305(n)) = self.cryptography {
34 Some(n)
35 } else {
36 None
37 }
38 }
39 pub fn set_sign(&mut self, sign: [u8; 32]) {
40 self.sign = Some(SigningAlgorithm::HmacSha256(sign));
41 }
42 pub fn get_sign(&self) -> Option<[u8; 32]> {
43 if let Some(SigningAlgorithm::HmacSha256(n)) = self.sign {
44 Some(n)
45 } else {
46 None
47 }
48 }
49 pub fn from_schemaed_string(addr: &str) -> Option<Self> {
50 let separator = addr.find("://")? + 3;
51 let protocol = Protocol::from_schemaed_string(&addr[..separator])?;
52 let address = SocketAddr::from_str(&addr[separator..]).ok()?;
53 Some(Connect {
54 host: address.ip().to_string(),
55 port: address.port(),
56 protocol,
57 cryptography: None,
58 sign: None,
59 })
60 }
61}
62
63impl Debug for Connect {
64 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
65 let mut debug = f.debug_struct("Connect");
66 debug.field("host", &self.host);
67 debug.field("port", &self.port);
68 debug.field("protocol", &self.protocol);
69 if self.cryptography.is_some() {
70 debug.field("cryptography", &"XXXXXX");
71 }
72 if self.sign.is_some() {
73 debug.field("sign", &"XXXXXX");
74 }
75 debug.finish()
76 }
77}
78
79#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
80pub enum Protocol {
81 TCP,
82 UDP,
83 HTTP,
84 TLS,
85 DTLS,
86 HTTPS,
87 QUIC,
88}
89
90impl Display for Protocol {
91 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92 write!(
93 f,
94 "{}",
95 match self {
96 Protocol::TCP => "tcp",
97 Protocol::UDP => "udp",
98 Protocol::HTTP => "http",
99 Protocol::HTTPS => "https",
100 Protocol::TLS => "tls",
101 Protocol::DTLS => "dtls",
102 Protocol::QUIC => "quic",
103 }
104 )
105 }
106}
107
108impl Protocol {
109 pub fn from_schemaed_string(addr: &str) -> Option<Self> {
110 match addr.to_lowercase().as_str() {
111 "tcp://" => Some(Protocol::TCP),
112 "udp://" => Some(Protocol::UDP),
113 "http://" => Some(Protocol::HTTP),
114 "https://" => Some(Protocol::HTTPS),
115 "tls://" => Some(Protocol::TLS),
116 "dtls://" => Some(Protocol::DTLS),
117 "quic://" => Some(Protocol::QUIC),
118 _ => None,
119 }
120 }
121}
122impl FromStr for Protocol {
123 type Err = serde_json::Error;
124 fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
125 serde_json::from_str(s)
126 }
127}
128#[derive(Serialize, Deserialize, Clone)]
129pub struct AgentInfo {
130 pub name: String,
131 pub socket_addr: String,
132 pub forward_addr: Option<String>,
133 pub system_info: Option<SystemInfo>,
134 pub publish_info: Vec<AgentPublishInfo>,
135 pub since: u64,
136 pub ping: u16,
137}
138
139impl std::fmt::Debug for AgentInfo {
140 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
141 let mut debug = f.debug_struct("AgentInfo");
142 debug.field("name", &self.name);
143 debug.field("socket_addr", &self.socket_addr);
144 if let Some(forward_addr) = &self.forward_addr {
145 debug.field("forward_addr", forward_addr);
146 }
147 if let Some(system_info) = &self.system_info.as_ref() {
148 debug.field("system_info", system_info);
149 }
150 if let Some(since) = &chrono::DateTime::from_timestamp(self.since as i64, 0) {
151 let datetime: chrono::DateTime<chrono::Local> =
152 chrono::DateTime::from_naive_utc_and_offset(
153 since.naive_utc(),
154 *chrono::Local::now().offset(),
155 );
156 debug.field("since", &datetime);
157 }
158 debug.field("ping", &self.ping);
159 debug.finish()
160 }
161}
162
163impl FromStr for Connect {
164 type Err = serde_json::Error;
165 fn from_str(s: &str) -> Result<Self, <Self as FromStr>::Err> {
166 serde_json::from_str(s)
167 }
168}