2022-01-03 21:29:04 +00:00
|
|
|
#![allow(dead_code)]
|
|
|
|
|
2021-11-22 16:28:30 +00:00
|
|
|
use crate::xx::*;
|
|
|
|
pub use async_executors::JoinHandle;
|
|
|
|
use async_executors::{AsyncStd, LocalSpawnHandleExt, SpawnHandleExt};
|
2022-05-17 20:55:53 +00:00
|
|
|
use async_std_resolver::{config, resolver, AsyncStdResolver};
|
2021-11-22 16:28:30 +00:00
|
|
|
use rand::prelude::*;
|
|
|
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
|
|
|
|
2022-05-17 20:55:53 +00:00
|
|
|
lazy_static::lazy_static! {
|
|
|
|
static ref RESOLVER: Arc<AsyncMutex<Option<AsyncStdResolver>>> = Arc::new(AsyncMutex::new(None));
|
|
|
|
}
|
|
|
|
|
2021-11-22 16:28:30 +00:00
|
|
|
pub fn get_timestamp() -> u64 {
|
|
|
|
match SystemTime::now().duration_since(UNIX_EPOCH) {
|
|
|
|
Ok(n) => n.as_micros() as u64,
|
|
|
|
Err(_) => panic!("SystemTime before UNIX_EPOCH!"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-17 02:57:28 +00:00
|
|
|
pub fn get_timestamp_string() -> String {
|
|
|
|
let dt = chrono::Utc::now();
|
|
|
|
dt.time().format("%H:%M:%S.3f").to_string()
|
|
|
|
}
|
|
|
|
|
2021-11-22 16:28:30 +00:00
|
|
|
pub fn random_bytes(dest: &mut [u8]) -> Result<(), String> {
|
|
|
|
let mut rng = rand::thread_rng();
|
|
|
|
rng.try_fill_bytes(dest).map_err(|err| format!("{:?}", err))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_random_u32() -> u32 {
|
|
|
|
let mut rng = rand::thread_rng();
|
|
|
|
rng.next_u32()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_random_u64() -> u64 {
|
|
|
|
let mut rng = rand::thread_rng();
|
|
|
|
rng.next_u64()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn sleep(millis: u32) {
|
|
|
|
if millis == 0 {
|
|
|
|
async_std::task::yield_now().await;
|
|
|
|
} else {
|
|
|
|
async_std::task::sleep(Duration::from_millis(u64::from(millis))).await;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn spawn<Out>(future: impl Future<Output = Out> + Send + 'static) -> JoinHandle<Out>
|
|
|
|
where
|
|
|
|
Out: Send + 'static,
|
|
|
|
{
|
|
|
|
AsyncStd
|
|
|
|
.spawn_handle(future)
|
|
|
|
.expect("async-std spawn should never error out")
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn spawn_local<Out>(future: impl Future<Output = Out> + 'static) -> JoinHandle<Out>
|
|
|
|
where
|
|
|
|
Out: 'static,
|
|
|
|
{
|
|
|
|
AsyncStd
|
|
|
|
.spawn_handle_local(future)
|
|
|
|
.expect("async-std spawn_local should never error out")
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn interval<F, FUT>(freq_ms: u32, callback: F) -> SystemPinBoxFuture<()>
|
|
|
|
where
|
|
|
|
F: Fn() -> FUT + Send + Sync + 'static,
|
|
|
|
FUT: Future<Output = ()> + Send,
|
|
|
|
{
|
|
|
|
let e = Eventual::new();
|
|
|
|
|
|
|
|
let ie = e.clone();
|
|
|
|
let jh = spawn(async move {
|
|
|
|
while timeout(freq_ms, ie.instance_clone(())).await.is_err() {
|
|
|
|
callback().await;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
Box::pin(async move {
|
|
|
|
e.resolve().await;
|
|
|
|
jh.await;
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub use async_std::future::TimeoutError;
|
|
|
|
|
|
|
|
pub async fn timeout<F, T>(dur_ms: u32, f: F) -> Result<T, TimeoutError>
|
|
|
|
where
|
|
|
|
F: Future<Output = T>,
|
|
|
|
{
|
|
|
|
async_std::future::timeout(Duration::from_millis(dur_ms as u64), f).await
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_concurrency() -> u32 {
|
|
|
|
num_cpus::get() as u32
|
|
|
|
}
|
|
|
|
|
2022-04-07 13:55:09 +00:00
|
|
|
pub async fn get_outbound_relay_peer() -> Option<crate::veilid_api::PeerInfo> {
|
|
|
|
panic!("Native Veilid should never require an outbound relay");
|
|
|
|
}
|
|
|
|
|
2021-11-22 16:28:30 +00:00
|
|
|
/*
|
|
|
|
pub fn async_callback<F, OF, EF, T, E>(fut: F, ok_fn: OF, err_fn: EF)
|
|
|
|
where
|
|
|
|
F: Future<Output = Result<T, E>> + Send + 'static,
|
|
|
|
OF: FnOnce(T) + Send + 'static,
|
|
|
|
EF: FnOnce(E) + Send + 'static,
|
|
|
|
{
|
|
|
|
spawn(Box::pin(async move {
|
|
|
|
match fut.await {
|
|
|
|
Ok(v) => ok_fn(v),
|
|
|
|
Err(e) => err_fn(e),
|
|
|
|
};
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
*/
|
2022-05-17 20:55:53 +00:00
|
|
|
|
|
|
|
async fn get_resolver() -> Result<AsyncStdResolver, String> {
|
|
|
|
let mut resolver_lock = RESOLVER.lock().await;
|
|
|
|
if let Some(r) = &*resolver_lock {
|
|
|
|
Ok(r.clone())
|
|
|
|
} else {
|
|
|
|
let resolver = resolver(
|
|
|
|
config::ResolverConfig::default(),
|
|
|
|
config::ResolverOpts::default(),
|
|
|
|
)
|
|
|
|
.await
|
|
|
|
.expect("failed to connect resolver");
|
|
|
|
|
|
|
|
*resolver_lock = Some(resolver.clone());
|
|
|
|
Ok(resolver)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn txt_lookup<S: AsRef<str>>(host: S) -> Result<Vec<String>, String> {
|
|
|
|
let resolver = get_resolver().await?;
|
|
|
|
let txt_result = resolver
|
|
|
|
.txt_lookup(host.as_ref())
|
|
|
|
.await
|
|
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
let mut out = Vec::new();
|
|
|
|
for x in txt_result.iter() {
|
|
|
|
for s in x.txt_data() {
|
|
|
|
out.push(String::from_utf8(s.to_vec()).map_err(|e| e.to_string())?);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(out)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn ptr_lookup(ip_addr: IpAddr) -> Result<String, String> {
|
|
|
|
let resolver = get_resolver().await?;
|
|
|
|
let ptr_result = resolver
|
|
|
|
.reverse_lookup(ip_addr)
|
|
|
|
.await
|
|
|
|
.map_err(|e| e.to_string())?;
|
|
|
|
if let Some(r) = ptr_result.iter().next() {
|
|
|
|
Ok(r.to_string().trim_end_matches('.').to_string())
|
|
|
|
} else {
|
|
|
|
Err("PTR lookup returned an empty string".to_owned())
|
|
|
|
}
|
|
|
|
}
|