mod udp;
mod tcp;
mod socket;
mod buffer;
pub use udp::{UdpTransport, UdpSocket};
pub use tcp::{TcpTransport, TcpStream};
pub use socket::{SocketConfig, bind_socket};
pub use buffer::{PacketBuffer, BufferPool};
use std::net::SocketAddr;
use std::time::Duration;
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use crate::error::Result;
use crate::types::IpVersion;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TransportConfig {
#[serde(default)]
pub ip_version: IpVersion,
#[serde(default = "default_send_buffer")]
pub send_buffer_size: usize,
#[serde(default = "default_recv_buffer")]
pub recv_buffer_size: usize,
#[serde(default = "default_connect_timeout", with = "humantime_serde")]
pub connect_timeout: Duration,
#[serde(default = "default_io_timeout", with = "humantime_serde")]
pub io_timeout: Duration,
#[serde(default = "default_keepalive", with = "humantime_serde")]
pub keepalive_interval: Duration,
#[serde(default = "default_nodelay")]
pub tcp_nodelay: bool,
#[serde(default = "default_reuse_addr")]
pub reuse_addr: bool,
#[serde(default)]
pub reuse_port: bool,
#[serde(default)]
pub mss: u32,
#[serde(default)]
pub tcp_fast_open: bool,
}
fn default_send_buffer() -> usize { 2 * 1024 * 1024 } fn default_recv_buffer() -> usize { 2 * 1024 * 1024 } fn default_connect_timeout() -> Duration { Duration::from_secs(10) }
fn default_io_timeout() -> Duration { Duration::from_secs(30) }
fn default_keepalive() -> Duration { Duration::from_secs(30) }
fn default_nodelay() -> bool { true }
fn default_reuse_addr() -> bool { true }
impl Default for TransportConfig {
fn default() -> Self {
Self {
ip_version: IpVersion::default(),
send_buffer_size: default_send_buffer(),
recv_buffer_size: default_recv_buffer(),
connect_timeout: default_connect_timeout(),
io_timeout: default_io_timeout(),
keepalive_interval: default_keepalive(),
tcp_nodelay: default_nodelay(),
reuse_addr: default_reuse_addr(),
reuse_port: false,
mss: 0,
tcp_fast_open: false,
}
}
}
#[async_trait]
pub trait Transport: Send + Sync {
fn local_addr(&self) -> Result<SocketAddr>;
fn remote_addr(&self) -> Option<SocketAddr>;
async fn send_to(&self, data: &[u8], addr: SocketAddr) -> Result<usize>;
async fn send(&self, data: &[u8]) -> Result<usize>;
async fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>;
async fn recv(&self, buf: &mut [u8]) -> Result<usize>;
async fn close(&self) -> Result<()>;
fn is_connected(&self) -> bool;
fn transport_type(&self) -> &'static str;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum TransportProtocol {
#[default]
Udp,
Tcp,
}
impl std::fmt::Display for TransportProtocol {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Udp => write!(f, "udp"),
Self::Tcp => write!(f, "tcp"),
}
}
}
pub fn create_transport(
protocol: TransportProtocol,
bind_addr: SocketAddr,
config: &TransportConfig,
) -> Result<Box<dyn Transport>> {
match protocol {
TransportProtocol::Udp => {
let transport = UdpTransport::bind(bind_addr, config)?;
Ok(Box::new(transport))
}
TransportProtocol::Tcp => {
let transport = TcpTransport::bind(bind_addr, config)?;
Ok(Box::new(transport))
}
}
}
pub async fn connect(
protocol: TransportProtocol,
remote_addr: SocketAddr,
bind_addr: Option<SocketAddr>,
config: &TransportConfig,
) -> Result<Box<dyn Transport>> {
match protocol {
TransportProtocol::Udp => {
let transport = UdpTransport::connect(remote_addr, bind_addr, config).await?;
Ok(Box::new(transport))
}
TransportProtocol::Tcp => {
let transport = TcpTransport::connect(remote_addr, bind_addr, config).await?;
Ok(Box::new(transport))
}
}
}
#[derive(Debug)]
pub struct TransportPacket {
pub data: Vec<u8>,
pub src_addr: SocketAddr,
pub dst_addr: SocketAddr,
pub timestamp: std::time::Instant,
}