Skip to content

Commit 2b40ca3

Browse files
authored
fix: improve pre-connect/register/connect stability (#230)
* fix: improve pre-connect/register/connect stability * refactor: move psk * fix: bad mod * feat: add local-only backend storage * feat: improve crypto data types * fix: return Vec/string for crypto types * fix: add enum helpers to UdpMode * docs: cleanup * fix: do not kill connections on first TLS error * fix: do not emit warnings for end of connections. use debug * wasm32-wasip1 initial support * wasm32-wasip1 initial support /0 * feat: allow wasm32-unknown-unknown for citadel_io * feat: tests mostly passing * feat: tests passing * fix: minor fixes * fix: higher stability * fix: lints * fix: race condition
1 parent 1b66a04 commit 2b40ca3

159 files changed

Lines changed: 2029 additions & 1137 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.cargo/config.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
[target.wasm32-wasi]
22
rustflags = ["-C", "target-feature=+atomics,+bulk-memory,+threads,+net"]
33

4+
[target.wasm32-wasip1]
5+
rustflags = ['--cfg', 'wasmedge', '--cfg', 'tokio_unstable']
6+
7+
[target.wasm32-wasip2]
8+
rustflags = ['--cfg', 'wasmedge', '--cfg', 'tokio_unstable']
9+
410
[profile.wasix]
511
opt-level = 3
612
inherits = "dev"

.github/workflows/validate.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ jobs:
124124

125125
misc_checks:
126126
name: miscellaneous
127-
runs-on: ubuntu-latest
127+
runs-on: macos-latest
128128
steps:
129129
- uses: Avarok-Cybersecurity/gh-actions-deps@master
130130
# - name: Install Valgrind

Cargo.toml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[workspace]
2-
resolver = "2"
2+
resolver = "3"
33

44
members = [
55
"citadel_sdk",
@@ -45,20 +45,18 @@ enum_primitive = { default-features = false, version = "0.1.1" }
4545
aes-gcm = { version = "0.10.3", default-features = false }
4646
chacha20poly1305 = { version = "0.10.1", default-features = false }
4747
log = { default-features = false, version = "0.4.17" }
48-
strum = { version = "0.26.2", default-features = false }
48+
strum = { version = "0.27.1", default-features = false }
49+
strum_macros = { version = "0.27.1", default-features = false }
4950
sha3 = { version = "0.10", default-features = false }
5051
kyber-pke = { version = "0.5.0", default-features = false }
5152
packed_struct = { version = "0.10.1" }
5253
getrandom = { version = "0.2.8", default-features = false }
5354
serde-big-array = { default-features = false, version = "0.5.0" }
5455
ascon-aead = { default-features = false, version = "0.4.0" }
55-
oqs = { version = "0.9.0", default-features = false }
56-
pqcrypto-falcon-wasi = { version = "0.2.14", default-features = false }
57-
pqcrypto-traits-wasi = { version = "0.3.4", default-features = false }
5856
tracing-subscriber = { version = "0.3.16" }
5957
reqwest_wasi = { version = "0.11.16", default-features = false }
6058
reqwest = { version = "0.12.7", default-features = false }
61-
tokio = { version = "1.36.0" }
59+
tokio = { version = "1.47.0" }
6260
bytes = { default-features = false, version = "1.3.0" }
6361
async-trait = { default-features = false, version = "0.1.61" }
6462
anyhow = { default-features = false, version = "1.0.68" }
@@ -101,15 +99,15 @@ multimap = { default-features = false, version = "0.9.0" }
10199
parking_lot = { version = "0.12.1" }
102100
twox-hash = { default-features = false, version = "1.6.3" }
103101
serde_json = { default-features = false, version = "1.0.91" }
104-
base64 = { version = "0.21.2", default-features = false }
102+
base64 = { version = "0.22", default-features = false }
105103
bstr = { default-features = false, version = "1.1.0" }
106104
sqlx = { version = "0.7.2" }
107105
redis-base = { package = "redis", version = "0.23.0" }
108106
mobc = { version = "0.8.1", default-features = false }
109107
jwt = { version = "0.16.0", default-features = false }
110108
openssl = { version = "0.10.66", default-features = false }
111109
chrono = { default-features = false, version = "0.4.23" }
112-
tokio-util = { version = "0.7.4", default-features = false }
110+
tokio-util = { version = "0.7.15", default-features = false }
113111
dirs2 = { default-features = false, version = "3.0.1" }
114112
embedded-semver = { version = "0.3.0", default-features = false }
115113
auto_impl = { default-features = false, version = "1.0.1" }
@@ -118,9 +116,11 @@ atomic = { default-features = false, version = "0.6.0" }
118116
bytemuck = { default-features = false, version = "1.13.1" }
119117
either = { default-features = false, version = "1.8.0" }
120118
once_cell = { default-features = false, version = "1.17.0" }
121-
webrtc-util = { version = "0.8.0" }
119+
webrtc-util = { version = "0.11.0" }
122120
embed-doc-image = { version = "0.1.4" }
123121
hyper = { version = "0.14.25" }
124122
sha256 = { version = "1.5.0" }
125123
tokio-openssl = { version = "0.6.3" }
126-
openssl-sys = { version = "0.9.104" }
124+
openssl-sys = { version = "0.9.104" }
125+
ml-dsa = { version = "0.0.4" }
126+
ts-rs = { version = "11", features = ["bytes"] }

Makefile.toml

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -80,23 +80,13 @@ command = "choco"
8080
args = ["install", "-y", "llvm", "openssl", "cmake"]
8181

8282
[tasks.docs]
83-
script_runner = "@rust"
84-
env = { "CARGO_MAKE_RUST_SCRIPT_PROVIDER" = "cargo-script" }
83+
script_runner = "@duckscript"
8584
dependencies = ["docs-html"]
8685
script = '''
87-
//! ```cargo
88-
fn main() {
89-
std::fs::copy(
90-
"./resources/avarok.png",
91-
"./target/doc/citadel_sdk/avarok.png",
92-
)
93-
.expect("Failed to copy crate logo when building documentation.");
94-
std::fs::copy(
95-
"./resources/favicon.png",
96-
"./target/doc/citadel_sdk/favicon.png",
97-
)
98-
.expect("Failed to copy crate favicon when building documentation.");
99-
}
86+
# Copy logo
87+
cp ./resources/avarok.png ./target/doc/citadel_sdk/avarok.png
88+
# Copy favicon
89+
cp ./resources/favicon.png ./target/doc/citadel_sdk/favicon.png
10090
'''
10191

10292
[tasks.install-llvm-tools]

async_ip/Cargo.toml

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,16 @@ license = "MIT OR Apache-2.0"
1313

1414
[features]
1515
default = ["std"]
16-
std = [
17-
"futures/std",
18-
"serde",
19-
]
20-
wasm = [
21-
]
16+
std = ["futures/std", "serde"]
17+
wasm = []
2218

23-
[target.'cfg(not(target_family = "wasm"))'.dependencies]
24-
reqwest = { workspace = true }
25-
26-
[target.'cfg(target_family = "wasm")'.dependencies]
27-
ureq = { version = "2.9.6", default-features = false }
19+
#[target.'cfg(not(target_family = "wasm"))'.dependencies]
20+
#reqwest = { workspace = true }
2821

2922
[dependencies]
30-
citadel_io = { workspace = true}
23+
citadel_io = { workspace = true }
3124
serde = { workspace = true, features = ["derive"], optional = true }
3225
futures = { workspace = true, features = ["alloc"] }
3326
async-trait = { workspace = true }
3427
auto_impl = { workspace = true }
28+
reqwest = { workspace = true }

async_ip/src/lib.rs

Lines changed: 31 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
//! async fn main() -> Result<(), async_ip::IpRetrieveError> {
2525
//! // Get both internal and external IP addresses
2626
//! use reqwest::Client;
27-
//! let ip_info = get_all::<Client>(None).await?;
27+
//! let ip_info = get_all(None).await?;
2828
//! println!("External IPv6: {:?}", ip_info.external_ipv6);
2929
//! println!("Internal IPv4: {:?}", ip_info.internal_ip);
3030
//! Ok(())
@@ -66,18 +66,11 @@
6666
unused_import_braces,
6767
variant_size_differences,
6868
unused_features,
69-
unused_results,
70-
warnings
69+
unused_results
7170
)]
7271

73-
use async_trait::async_trait;
74-
use auto_impl::auto_impl;
75-
#[cfg(not(target_family = "wasm"))]
76-
use reqwest::Client;
7772
use std::fmt::Formatter;
7873
use std::net::IpAddr;
79-
#[cfg(not(target_family = "wasm"))]
80-
use std::net::SocketAddr;
8174
use std::str::FromStr;
8275

8376
// use http since it's 2-3x faster
@@ -112,24 +105,23 @@ impl IpAddressInfo {
112105
}
113106

114107
/// Gets IP info concurrently using default multiple internal sources
115-
pub async fn get_all_multi_concurrent<T: AsyncHttpGetClient>(
116-
client: Option<T>,
108+
pub async fn get_all_multi_concurrent(
109+
client: Option<reqwest::Client>,
117110
) -> Result<IpAddressInfo, IpRetrieveError> {
118111
get_all_multi_concurrent_from(client, &[URL_V6, URL_V6_1, URL_V6_2]).await
119112
}
120113

121114
/// Uses multiple url addrs to obtain the information
122-
pub async fn get_all_multi_concurrent_from<T: AsyncHttpGetClient>(
123-
client: Option<T>,
115+
pub async fn get_all_multi_concurrent_from(
116+
client: Option<reqwest::Client>,
124117
v6_addrs: &[&str],
125118
) -> Result<IpAddressInfo, IpRetrieveError> {
126-
let client = client.map(|client| Box::new(client) as Box<dyn AsyncHttpGetClient>);
127-
let client = &client.unwrap_or_else(|| Box::new(get_default_client()));
119+
let client = &client.unwrap_or_else(get_default_client);
128120
let internal_ipv4_future = get_internal_ip(false);
129121
let external_ipv6_future = futures::future::select_ok(
130122
v6_addrs
131123
.iter()
132-
.map(|addr| Box::pin(get_ip_from(Some(client), addr)))
124+
.map(|addr| Box::pin(get_ip_from(Some(client.clone()), addr)))
133125
.collect::<Vec<_>>(),
134126
);
135127

@@ -145,20 +137,16 @@ pub async fn get_all_multi_concurrent_from<T: AsyncHttpGetClient>(
145137
}
146138

147139
/// Returns all possible IPs for this node
148-
pub async fn get_all<T: AsyncHttpGetClient>(
149-
client: Option<T>,
150-
) -> Result<IpAddressInfo, IpRetrieveError> {
140+
pub async fn get_all(client: Option<reqwest::Client>) -> Result<IpAddressInfo, IpRetrieveError> {
151141
get_all_from(client, URL_V6).await
152142
}
153143

154144
/// Gets IP info concurrently using custom multiple internal sources
155-
pub async fn get_all_from<T: AsyncHttpGetClient>(
156-
client: Option<T>,
145+
pub async fn get_all_from(
146+
client: Option<reqwest::Client>,
157147
v6_addr: &str,
158148
) -> Result<IpAddressInfo, IpRetrieveError> {
159-
let client = client
160-
.map(|client| Box::new(client) as Box<dyn AsyncHttpGetClient>)
161-
.unwrap_or_else(|| Box::new(get_default_client()));
149+
let client = client.unwrap_or_else(get_default_client);
162150
let internal_ipv4_future = get_internal_ip(false);
163151
let external_ipv6_future = get_ip_from(Some(client), v6_addr);
164152
let (res0, res2) = citadel_io::tokio::join!(internal_ipv4_future, external_ipv6_future);
@@ -177,15 +165,23 @@ pub async fn get_all_from<T: AsyncHttpGetClient>(
177165
/// instead.
178166
///
179167
/// If a reqwest client is supplied, this function will use that client to get the information. None by default.
180-
pub async fn get_ip_from<T: AsyncHttpGetClient>(
181-
client: Option<T>,
168+
pub async fn get_ip_from(
169+
client: Option<reqwest::Client>,
182170
addr: &str,
183171
) -> Result<IpAddr, IpRetrieveError> {
184-
let client = client
185-
.map(|client| Box::new(client) as Box<dyn AsyncHttpGetClient>)
186-
.unwrap_or_else(|| Box::new(get_default_client()));
172+
let client = client.unwrap_or_else(get_default_client);
173+
174+
let resp = client
175+
.get(addr)
176+
.send()
177+
.await
178+
.map_err(|err| IpRetrieveError::Error(err.to_string()))?;
179+
180+
let text = resp
181+
.text()
182+
.await
183+
.map_err(|err| IpRetrieveError::Error(err.to_string()))?;
187184

188-
let text = client.get(addr).await?;
189185
IpAddr::from_str(text.as_str()).map_err(|err| IpRetrieveError::Error(err.to_string()))
190186
}
191187

@@ -198,7 +194,6 @@ pub async fn get_internal_ip(ipv6: bool) -> Option<IpAddr> {
198194
}
199195
}
200196

201-
#[cfg(not(target_family = "wasm"))]
202197
/// Returns the internal ipv4 address of this node
203198
pub async fn get_internal_ipv4() -> Option<IpAddr> {
204199
let socket = citadel_io::tokio::net::UdpSocket::bind(addr("0.0.0.0:0")?)
@@ -208,12 +203,6 @@ pub async fn get_internal_ipv4() -> Option<IpAddr> {
208203
socket.local_addr().ok().map(|sck| sck.ip())
209204
}
210205

211-
#[cfg(target_family = "wasm")]
212-
async fn get_internal_ipv4() -> Option<IpAddr> {
213-
None
214-
}
215-
216-
#[cfg(not(target_family = "wasm"))]
217206
async fn get_internal_ipv6() -> Option<IpAddr> {
218207
let socket = citadel_io::tokio::net::UdpSocket::bind(addr("[::]:0")?)
219208
.await
@@ -225,25 +214,13 @@ async fn get_internal_ipv6() -> Option<IpAddr> {
225214
socket.local_addr().ok().map(|sck| sck.ip())
226215
}
227216

228-
#[cfg(target_family = "wasm")]
229-
async fn get_internal_ipv6() -> Option<IpAddr> {
230-
None
231-
}
232-
233-
#[cfg(not(target_family = "wasm"))]
234-
fn addr(addr: &str) -> Option<SocketAddr> {
235-
SocketAddr::from_str(addr).ok()
217+
fn addr(addr: &str) -> Option<std::net::SocketAddr> {
218+
std::net::SocketAddr::from_str(addr).ok()
236219
}
237220

238-
#[cfg(not(target_family = "wasm"))]
239221
/// Returns a default client
240-
pub fn get_default_client() -> Client {
241-
Client::builder().tcp_nodelay(true).build().unwrap()
242-
}
243-
#[cfg(target_family = "wasm")]
244-
/// Returns a default client
245-
fn get_default_client() -> UreqClient {
246-
UreqClient
222+
pub fn get_default_client() -> reqwest::Client {
223+
reqwest::Client::builder().build().unwrap()
247224
}
248225

249226
/// The default error type for this crate
@@ -256,59 +233,7 @@ pub enum IpRetrieveError {
256233
impl std::fmt::Display for IpRetrieveError {
257234
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
258235
match self {
259-
IpRetrieveError::Error(err) => write!(f, "{}", err),
236+
IpRetrieveError::Error(err) => write!(f, "{err}"),
260237
}
261238
}
262239
}
263-
264-
#[async_trait]
265-
#[auto_impl(Box, &)]
266-
/// An async http client
267-
pub trait AsyncHttpGetClient: Send + Sync {
268-
/// Async Get
269-
async fn get(&self, addr: &str) -> Result<String, IpRetrieveError>;
270-
}
271-
272-
#[cfg(not(target_family = "wasm"))]
273-
#[async_trait]
274-
impl AsyncHttpGetClient for Client {
275-
async fn get(&self, addr: &str) -> Result<String, IpRetrieveError> {
276-
let resp = self
277-
.get(addr)
278-
.send()
279-
.await
280-
.map_err(|err| IpRetrieveError::Error(err.to_string()))?;
281-
282-
resp.text()
283-
.await
284-
.map_err(|err| IpRetrieveError::Error(err.to_string()))
285-
}
286-
}
287-
288-
#[async_trait]
289-
impl AsyncHttpGetClient for () {
290-
async fn get(&self, _addr: &str) -> Result<String, IpRetrieveError> {
291-
unimplemented!("Stub implementation for AsyncHttpGetClient")
292-
}
293-
}
294-
295-
#[cfg(target_family = "wasm")]
296-
/// Ureq client
297-
pub struct UreqClient;
298-
299-
#[cfg(target_family = "wasm")]
300-
#[async_trait]
301-
impl AsyncHttpGetClient for UreqClient {
302-
async fn get(&self, addr: &str) -> Result<String, IpRetrieveError> {
303-
let addr = addr.to_string();
304-
citadel_io::tokio::task::spawn_blocking(move || {
305-
ureq::get(&addr)
306-
.call()
307-
.map_err(|err| IpRetrieveError::Error(err.to_string()))?
308-
.into_string()
309-
.map_err(|err| IpRetrieveError::Error(err.to_string()))
310-
})
311-
.await
312-
.map_err(|err| IpRetrieveError::Error(err.to_string()))?
313-
}
314-
}

async_ip/tests/primary.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ mod tests {
55

66
#[tokio::test]
77
async fn get() {
8-
let addrs = get_all::<()>(None).await.unwrap();
8+
let addrs = get_all(None).await.unwrap();
99
println!("Addrs: {addrs:?}");
1010
}
1111

1212
#[tokio::test]
1313
async fn get_multi() {
14-
let addrs = get_all_multi_concurrent::<()>(None).await.unwrap();
14+
let addrs = get_all_multi_concurrent(None).await.unwrap();
1515
println!("Addrs: {addrs:?}");
1616
}
1717
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules/
2+
dist/
3+
*.log
4+
.DS_Store

0 commit comments

Comments
 (0)