use std::{
fmt::Debug,
net::SocketAddr,
sync::{Arc, atomic::AtomicU64},
};
use bincode::{Decode, Encode};
use iroh::endpoint::{Connection, ConnectionError, ReadError};
use thiserror::Error;
use tokio::io::AsyncWriteExt;
use crate::TunnelProtocol;
pub const TUNNEL_FORWARDER_BUFFER_SIZE: usize = 1024;
pub const CONNECTION_TIMEOUT_SECONDS: u64 = 20;
pub struct LocalClientConnection {
pub client_local_addr: SocketAddr,
pub client_virtual_addr: SocketAddr,
pub last_active: Arc<AtomicU64>,
}
pub async fn send_packet<P: Encode + Debug>(conn: &Connection, packet: P) -> std::io::Result<()> {
tracing::debug!("Sending packet: {:?}", packet);
let mut send = conn.open_uni().await?;
let data = bincode::encode_to_vec(&packet, bincode::config::standard()).unwrap();
send.write_all(&data).await?;
send.flush().await?;
send.finish()?;
Ok(())
}
#[derive(Error, Debug)]
pub enum ReceivePacketError {
#[error("io error: {0}")]
Io(#[from] std::io::Error),
#[error("decode error: {0}")]
Decode(#[from] bincode::error::DecodeError),
#[error("connection error: {0}")]
Connection(#[from] ConnectionError),
#[error("read error: {0}")]
Read(#[from] ReadError),
}
pub async fn receive_packet<P: Decode<()> + Debug>(
conn: &Connection,
) -> Result<P, ReceivePacketError> {
let mut recv = conn.accept_uni().await?;
let mut buf = Vec::new();
loop {
let mut data = vec![0; 1024];
if let Some(n) = recv.read(&mut data).await? {
buf.extend_from_slice(&data[..n]);
continue;
}
break;
}
let packet = bincode::decode_from_slice(&buf, bincode::config::standard())?.0;
tracing::debug!("Received packet: {:?}", packet);
Ok(packet)
}
#[derive(Encode, Decode, Debug)]
pub enum Client2HostControlMsg {
ConnReq {
local_addr: SocketAddr,
},
}
pub trait TunnelCommon {
fn secret(&self) -> [u8; 32];
fn protocol(&self) -> TunnelProtocol;
fn is_running(&self) -> bool;
fn name(&self) -> String;
#[allow(async_fn_in_trait)]
async fn num_active_connections(&self) -> usize;
fn addr(&self) -> SocketAddr;
}