start, reverse guard, cli-frontend for server and client
This commit is contained in:
12
osn/Cargo.toml
Normal file
12
osn/Cargo.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "osn"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
tokio.workspace = true
|
||||
bytes.workspace = true
|
||||
anyhow.workspace = true
|
||||
thiserror.workspace = true
|
||||
tracing.workspace = true
|
||||
async-trait = "0.1"
|
||||
3
osn/src/lib.rs
Normal file
3
osn/src/lib.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub mod tun;
|
||||
|
||||
pub use tun::{DummyTun, Router, TunConfig, TunDevice, TunError};
|
||||
95
osn/src/tun.rs
Normal file
95
osn/src/tun.rs
Normal file
@@ -0,0 +1,95 @@
|
||||
//! Virtual network interface (TUN/TAP) abstraction
|
||||
|
||||
use bytes::Bytes;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum TunError {
|
||||
#[error("failed to create interface: {0}")]
|
||||
Create(String),
|
||||
#[error("io error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
#[error("interface not ready")]
|
||||
NotReady,
|
||||
}
|
||||
|
||||
/// TUN device configuration
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TunConfig {
|
||||
pub name: String,
|
||||
pub address: [u8; 4],
|
||||
pub netmask: [u8; 4],
|
||||
pub mtu: u16,
|
||||
}
|
||||
|
||||
impl Default for TunConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "ostp0".into(),
|
||||
address: [10, 0, 0, 1],
|
||||
netmask: [255, 255, 255, 0],
|
||||
mtu: 1400,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Abstract TUN device trait
|
||||
#[async_trait::async_trait]
|
||||
pub trait TunDevice: Send + Sync {
|
||||
async fn read(&self) -> Result<Bytes, TunError>;
|
||||
async fn write(&self, data: &[u8]) -> Result<usize, TunError>;
|
||||
fn mtu(&self) -> u16;
|
||||
}
|
||||
|
||||
/// Placeholder TUN implementation (platform-specific impl needed)
|
||||
pub struct DummyTun {
|
||||
config: TunConfig,
|
||||
}
|
||||
|
||||
impl DummyTun {
|
||||
pub fn new(config: TunConfig) -> Self {
|
||||
Self { config }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl TunDevice for DummyTun {
|
||||
async fn read(&self) -> Result<Bytes, TunError> {
|
||||
// Platform-specific: use wintun on Windows, tun-tap on Linux
|
||||
Err(TunError::NotReady)
|
||||
}
|
||||
|
||||
async fn write(&self, _data: &[u8]) -> Result<usize, TunError> {
|
||||
Err(TunError::NotReady)
|
||||
}
|
||||
|
||||
fn mtu(&self) -> u16 {
|
||||
self.config.mtu
|
||||
}
|
||||
}
|
||||
|
||||
/// IP packet routing helper
|
||||
pub struct Router {
|
||||
default_gateway: [u8; 4],
|
||||
}
|
||||
|
||||
impl Router {
|
||||
pub fn new(gateway: [u8; 4]) -> Self {
|
||||
Self {
|
||||
default_gateway: gateway,
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if IP should be tunneled
|
||||
pub fn should_tunnel(&self, dest_ip: &[u8; 4]) -> bool {
|
||||
// Don't tunnel local/private ranges by default
|
||||
!matches!(
|
||||
dest_ip,
|
||||
[10, ..] | [127, ..] | [192, 168, ..] | [172, 16..=31, ..]
|
||||
)
|
||||
}
|
||||
|
||||
pub fn gateway(&self) -> [u8; 4] {
|
||||
self.default_gateway
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user