use byteorder::{ByteOrder, BE};
use std::{fmt, num::NonZeroU128, sync::Arc};
use tokio::sync::mpsc;
use x25519_dalek::SharedSecret;
fn debug_id(id: u128) -> String {
let mut s = format!("{id:016x}");
s.truncate(6);
s
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ConnId(pub u128);
impl fmt::Debug for ConnId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", debug_id(self.0))
}
}
impl fmt::Display for ConnId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:016x}", self.0)
}
}
impl ConnId {
pub(crate) fn generate() -> Self {
Self(rand::random())
}
}
#[derive(Clone, Copy, PartialEq, Eq)]
pub(crate) struct EncryptedConnId(pub u128);
impl fmt::Debug for EncryptedConnId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "*{}*", debug_id(self.0))
}
}
impl EncryptedConnId {
pub fn new(id: ConnId, secret: &SharedSecret) -> Self {
let key = BE::read_u128(secret.as_bytes());
Self(key ^ id.0)
}
pub fn decrypt(self, secret: &SharedSecret) -> ConnId {
let key = BE::read_u128(secret.as_bytes());
ConnId(key ^ self.0)
}
}
#[derive(Clone)]
pub(crate) struct OwnedConnId(Arc<OwnedConnIdInner>);
struct OwnedConnIdInner {
id: ConnId,
dropped_tx: Option<mpsc::UnboundedSender<ConnId>>,
}
impl fmt::Display for OwnedConnId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", &self.0.id)
}
}
impl fmt::Debug for OwnedConnId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", &self.0.id)
}
}
impl Drop for OwnedConnIdInner {
fn drop(&mut self) {
if let Some(dropped_tx) = self.dropped_tx.take() {
let _ = dropped_tx.send(self.id);
}
}
}
impl OwnedConnId {
pub fn new(id: ConnId, dropped_tx: mpsc::UnboundedSender<ConnId>) -> Self {
Self(Arc::new(OwnedConnIdInner { id, dropped_tx: Some(dropped_tx) }))
}
pub fn untracked(id: ConnId) -> Self {
Self(Arc::new(OwnedConnIdInner { id, dropped_tx: None }))
}
pub fn get(&self) -> ConnId {
self.0.id
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LinkId(pub u128);
impl fmt::Debug for LinkId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", debug_id(self.0))
}
}
impl fmt::Display for LinkId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:016x}", self.0)
}
}
impl LinkId {
pub(crate) fn generate() -> Self {
Self(rand::random())
}
}
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ServerId(pub NonZeroU128);
impl fmt::Debug for ServerId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", debug_id(self.0.get()))
}
}
impl fmt::Display for ServerId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:016x}", self.0)
}
}
impl ServerId {
pub(crate) fn generate() -> Self {
Self(NonZeroU128::new(rand::random_range(1..=u128::MAX)).unwrap())
}
}