use crate::asn::service::AsnLookup;
use crate::dns::service::RdnsLookup;
use crate::public_ip::service::StunClient;
use std::sync::Arc;
#[derive(Clone, Debug)]
pub struct Services {
pub asn: Arc<AsnLookup>,
pub rdns: Arc<RdnsLookup>,
pub stun: Arc<StunClient>,
}
impl Services {
pub fn new() -> Self {
Self {
asn: Arc::new(AsnLookup::new()),
rdns: Arc::new(RdnsLookup::new()),
stun: Arc::new(StunClient::new()),
}
}
pub fn with_services(
asn: Option<AsnLookup>,
rdns: Option<RdnsLookup>,
stun: Option<StunClient>,
) -> Self {
Self {
asn: Arc::new(asn.unwrap_or_default()),
rdns: Arc::new(rdns.unwrap_or_default()),
stun: Arc::new(stun.unwrap_or_default()),
}
}
pub fn with_caches(
asn_cache: Option<crate::asn::cache::AsnCache>,
rdns_cache: Option<crate::dns::cache::RdnsCache>,
stun_cache: Option<crate::public_ip::stun_cache::StunCache>,
) -> Self {
let asn = if let Some(cache) = asn_cache {
AsnLookup::with_cache(cache)
} else {
AsnLookup::new()
};
let rdns = if let Some(cache) = rdns_cache {
RdnsLookup::with_cache(cache)
} else {
RdnsLookup::new()
};
let stun = if let Some(cache) = stun_cache {
StunClient::with_cache(
cache,
vec![
"stun.l.google.com:19302".to_string(),
"stun1.l.google.com:19302".to_string(),
],
)
} else {
StunClient::new()
};
Self {
asn: Arc::new(asn),
rdns: Arc::new(rdns),
stun: Arc::new(stun),
}
}
pub async fn clear_all_caches(&self) {
self.asn.clear_cache().await;
self.rdns.clear_cache().await;
self.stun.clear_cache().await;
}
}
impl Default for Services {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_services_creation() {
let services = Services::new();
let ip: std::net::IpAddr = "192.168.1.1".parse().unwrap();
let _ = services.asn.lookup(ip).await;
services.clear_all_caches().await;
}
#[tokio::test]
async fn test_services_with_custom() {
use std::time::Duration;
let custom_rdns = RdnsLookup::with_ttl(Duration::from_secs(120));
let services = Services::with_services(None, Some(custom_rdns), None);
let ip: std::net::IpAddr = "8.8.8.8".parse().unwrap();
let _ = services.rdns.lookup(ip).await;
}
#[tokio::test]
async fn test_services_clone() {
let services1 = Services::new();
let services2 = services1.clone();
let ip: std::net::IpAddr = "10.0.0.1".parse().unwrap();
let _ = services1.asn.lookup(ip).await;
let _ = services2.asn.lookup(ip).await;
}
}