161 lines
3.8 KiB
Rust
161 lines
3.8 KiB
Rust
use crate::config;
|
|
use crate::utils::SDLanError;
|
|
use dashmap::DashMap;
|
|
use std::net::{IpAddr, SocketAddr};
|
|
use std::path::Path;
|
|
use std::sync::Arc;
|
|
|
|
pub struct MyDashMap<T>(DashMap<String, Arc<T>>);
|
|
|
|
impl<T> MyDashMap<T> {
|
|
pub fn new() -> Self {
|
|
MyDashMap(DashMap::new())
|
|
}
|
|
|
|
pub fn get(&self, key: &str) -> Option<Arc<T>> {
|
|
if let Some(t) = self.0.get(key) {
|
|
return Some(t.clone());
|
|
}
|
|
None
|
|
}
|
|
|
|
pub fn insert(&self, key: String, value: Arc<T>) -> Option<Arc<T>> {
|
|
self.0.insert(key, value)
|
|
}
|
|
|
|
pub fn remove(&self, key: &str) -> Option<(String, Arc<T>)> {
|
|
self.0.remove(key)
|
|
}
|
|
|
|
pub fn clear(&self) {
|
|
self.0.clear()
|
|
}
|
|
}
|
|
|
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
|
|
|
pub fn get_timestamp_after_duration(d: Duration) -> u64 {
|
|
if let Some(t) = SystemTime::now().checked_add(d) {
|
|
t.duration_since(UNIX_EPOCH).unwrap().as_secs()
|
|
} else {
|
|
0
|
|
}
|
|
}
|
|
pub fn get_current_timestamp() -> u64 {
|
|
SystemTime::now()
|
|
.duration_since(UNIX_EPOCH)
|
|
.unwrap()
|
|
.as_secs()
|
|
}
|
|
|
|
use crate::peer::SdlanSock;
|
|
|
|
use super::{gen_uuid, Mac, Result, BROADCAST_MAC, IPV6_MULTICAST_MAC, MULTICAST_MAC};
|
|
use std::fs::{File, OpenOptions};
|
|
use std::io::{Read, Write};
|
|
|
|
pub fn save_to_file(idfile: &str, content: &str) -> Result<()> {
|
|
if idfile.len() == 0 {
|
|
return Err(SDLanError::IOError("file is empty".to_owned()));
|
|
}
|
|
|
|
let filepath = Path::new(idfile);
|
|
OpenOptions::new()
|
|
.create(true)
|
|
.write(true)
|
|
.open(filepath)?
|
|
.write_all(content.as_bytes())?;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn create_or_load_uuid(mut idfile: &str, size: Option<u8>) -> Result<String> {
|
|
if idfile.len() == 0 {
|
|
idfile = "./.id";
|
|
}
|
|
let filepath = Path::new(idfile);
|
|
if filepath.exists() {
|
|
let mut result = String::new();
|
|
File::open(filepath)?.read_to_string(&mut result)?;
|
|
let result = result.trim().to_string();
|
|
return Ok(result);
|
|
} else {
|
|
let mut uuid = gen_uuid();
|
|
if let Some(size) = size {
|
|
uuid.truncate(size as usize);
|
|
}
|
|
OpenOptions::new()
|
|
.create(true)
|
|
.write(true)
|
|
.open(filepath)?
|
|
.write_all(uuid.as_bytes())?;
|
|
return Ok(uuid);
|
|
}
|
|
}
|
|
|
|
// get sdlansock info from socketaddr
|
|
pub fn get_sdlan_sock_from_socketaddr(addr: SocketAddr) -> Result<SdlanSock> {
|
|
let port = addr.port();
|
|
let ip = addr.ip();
|
|
match ip {
|
|
IpAddr::V4(ipv4) => {
|
|
let v4: u32 = ipv4.into();
|
|
let res = SdlanSock {
|
|
family: config::AF_INET,
|
|
port: port,
|
|
// has_v6: false,
|
|
// v6_port: 0,
|
|
v4: v4.to_be_bytes(),
|
|
v6: [0; 16],
|
|
};
|
|
Ok(res)
|
|
}
|
|
IpAddr::V6(ipv6) => {
|
|
let res = SdlanSock {
|
|
family: config::AF_INET6,
|
|
port: port,
|
|
v4: [0; 4],
|
|
v6: ipv6.octets(),
|
|
};
|
|
Ok(res)
|
|
}
|
|
}
|
|
}
|
|
|
|
#[inline]
|
|
pub fn is_broadcast(mac: &Mac) -> bool {
|
|
*mac == BROADCAST_MAC
|
|
}
|
|
|
|
#[inline]
|
|
pub fn is_multicast(mac: &Mac) -> bool {
|
|
(mac[..3] == MULTICAST_MAC[..3]) && ((mac[3] >> 7) != 0x01)
|
|
}
|
|
|
|
#[inline]
|
|
pub fn is_ipv6_multicast(mac: &Mac) -> bool {
|
|
mac[..2] == IPV6_MULTICAST_MAC[..2]
|
|
}
|
|
|
|
#[inline]
|
|
pub fn is_multi_broadcast(mac: &Mac) -> bool {
|
|
is_broadcast(mac) || is_multicast(mac) || is_ipv6_multicast(mac)
|
|
}
|
|
|
|
pub fn ip_to_string(ip: &u32) -> String {
|
|
format!(
|
|
"{}.{}.{}.{}",
|
|
((ip >> 24) & 0xff) as u8,
|
|
((ip >> 16) & 0xff) as u8,
|
|
((ip >> 8) & 0xff) as u8,
|
|
(ip & 0xff) as u8,
|
|
)
|
|
}
|
|
|
|
pub fn net_bit_len_to_mask(len: u8) -> u32 {
|
|
let mut res = 0u32;
|
|
for i in 1..=len {
|
|
res |= 1 << (32 - i);
|
|
}
|
|
res
|
|
}
|