mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-03 21:21:32 +00:00
network: implement support for smoltcp and ipstack
This commit is contained in:
@ -1,21 +1,32 @@
|
||||
use std::os::fd::AsRawFd;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use advmac::MacAddr6;
|
||||
use anyhow::{anyhow, Result};
|
||||
use futures::TryStreamExt;
|
||||
use futures::channel::oneshot;
|
||||
use futures::{try_join, TryStreamExt};
|
||||
use ipstack::stream::IpStackStream;
|
||||
use log::{debug, error, info, warn};
|
||||
use netlink_packet_route::link::LinkAttribute;
|
||||
use raw_socket::{AsyncRawSocket, RawSocket};
|
||||
use smoltcp::iface::{Config, Interface, SocketSet};
|
||||
use smoltcp::time::Instant;
|
||||
use smoltcp::wire::{HardwareAddress, IpCidr};
|
||||
use tokio::net::TcpStream;
|
||||
use tokio::time::sleep;
|
||||
use udp_stream::UdpStream;
|
||||
|
||||
mod raw_socket;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct NetworkBackend {
|
||||
pub network: String,
|
||||
pub interface: String,
|
||||
}
|
||||
|
||||
pub struct NetworkService {
|
||||
pub network: String,
|
||||
}
|
||||
@ -27,8 +38,9 @@ impl NetworkService {
|
||||
}
|
||||
|
||||
impl NetworkBackend {
|
||||
pub fn new(iface: &str) -> Result<NetworkBackend> {
|
||||
pub fn new(network: &str, iface: &str) -> Result<NetworkBackend> {
|
||||
Ok(NetworkBackend {
|
||||
network: network.to_string(),
|
||||
interface: iface.to_string(),
|
||||
})
|
||||
}
|
||||
@ -56,14 +68,16 @@ impl NetworkBackend {
|
||||
}
|
||||
|
||||
pub async fn run(&mut self) -> Result<()> {
|
||||
try_join!(self.run_internet_stack(), self.run_virtual_host_stack()).map(|_| ())
|
||||
}
|
||||
|
||||
async fn run_internet_stack(&self) -> Result<()> {
|
||||
let mut config = ipstack::IpStackConfig::default();
|
||||
config.mtu(1500);
|
||||
config.tcp_timeout(std::time::Duration::from_secs(600)); // 10 minutes
|
||||
config.udp_timeout(std::time::Duration::from_secs(10)); // 10 seconds
|
||||
config.tcp_timeout(std::time::Duration::from_secs(600));
|
||||
config.udp_timeout(std::time::Duration::from_secs(10));
|
||||
|
||||
let mut socket = RawSocket::new(&self.interface)?;
|
||||
socket.bind_interface()?;
|
||||
let socket = AsyncRawSocket::new(socket)?;
|
||||
let socket = AsyncRawSocket::bind(&self.interface)?;
|
||||
let mut stack = ipstack::IpStack::new(config, socket);
|
||||
|
||||
while let Ok(stream) = stack.accept().await {
|
||||
@ -72,7 +86,40 @@ impl NetworkBackend {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn process_stream(&mut self, stream: IpStackStream) -> Result<()> {
|
||||
async fn run_virtual_host_stack(&self) -> Result<()> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
let me = self.clone();
|
||||
thread::spawn(move || {
|
||||
let _ = tx.send(me.run_virtual_host_stack_blocking());
|
||||
});
|
||||
rx.await?
|
||||
}
|
||||
|
||||
fn run_virtual_host_stack_blocking(&self) -> Result<()> {
|
||||
let address = IpCidr::from_str(&self.network)
|
||||
.map_err(|_| anyhow!("failed to parse cidr: {}", self.network))?;
|
||||
let addresses: Vec<IpCidr> = vec![address];
|
||||
let mut socket = RawSocket::new(&self.interface)?;
|
||||
let mac = MacAddr6::random();
|
||||
let mac = HardwareAddress::Ethernet(smoltcp::wire::EthernetAddress(mac.to_array()));
|
||||
let config = Config::new(mac);
|
||||
let mut iface = Interface::new(config, &mut socket, Instant::now());
|
||||
iface.update_ip_addrs(|addrs| {
|
||||
addrs
|
||||
.extend_from_slice(&addresses)
|
||||
.expect("failed to set ip addresses");
|
||||
});
|
||||
|
||||
let mut sockets = SocketSet::new(vec![]);
|
||||
let fd = socket.as_raw_fd();
|
||||
loop {
|
||||
let timestamp = Instant::now();
|
||||
iface.poll(timestamp, &mut socket, &mut sockets);
|
||||
smoltcp::phy::wait(fd, iface.poll_delay(timestamp, &sockets))?;
|
||||
}
|
||||
}
|
||||
|
||||
async fn process_stream(&self, stream: IpStackStream) -> Result<()> {
|
||||
match stream {
|
||||
IpStackStream::Tcp(mut tcp) => {
|
||||
debug!("tcp: {}", tcp.peer_addr());
|
||||
@ -160,7 +207,7 @@ impl NetworkService {
|
||||
spawned: Arc<Mutex<Vec<String>>>,
|
||||
) -> Result<()> {
|
||||
let interface = interface.to_string();
|
||||
let mut network = NetworkBackend::new(&interface)?;
|
||||
let mut network = NetworkBackend::new(&self.network, &interface)?;
|
||||
info!("initializing network backend for interface {}", interface);
|
||||
network.init().await?;
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
|
Reference in New Issue
Block a user