/ipstack

Asynchronous lightweight implementation of TCP/IP stack for Tun device

Primary LanguageRustApache License 2.0Apache-2.0

An asynchronous lightweight implementation of TCP/IP stack for Tun device. Unstable, under development.

Usage

use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use udp_stream::UdpStream;
use tokio::io{AsyncRead, AsyncWrite};
async fn copy_from_lhs_to_rhs(lhs:impl AsyncRead + AsyncWrite, rhs:impl AsyncRead + AsyncWrite){
	let (lhs_reader,lhs_writer) = tokio::io::split(lhs);
	let (rhs_reader, rhs_writer) = tokio::io::split(rhs);
        tokio::join! {
		tokio::io::copy(&mut lhs_reader, &mut rhs_writer) ,
		tokio::io::copy(&mut rhs_reader, &mut lhs_writer),
        }
}
#[tokio::main]
async fn main(){
	const MTU: u16 = 1500;
	let ipv4 = Ipv4Addr::new(10, 0, 0, 1);
	let mut config = tun::Configuration::default();
        config
         .address(ipv4)
         .netmask((255, 255, 255, 0))
         .mtu(MTU as i32)
         .up();

        let mut ipstack_config = ipstack::IpStackConfig::default();
        ipstack_config.mtu(MTU);
        ipstack_config.packet_info(cfg!(target_family = "unix"));
	let mut ip_stack = ipstack::IpStack::new(ipstack_config,tun::create_as_async(&config).unwrap());
	while let Ok(stream) = ip_stack.accept().await{
		match stream{
			IpStackStream::Tcp(tcp) => {
				let rhs = TcpStream::connect("1.1.1.1:80").await.unwrap();
				tokio::spawn(async move {
                                  copy_from_lhs_to_rhs(tcp,rhs).await;
                                });
			}
			IpStackStream::Udp(udp) => {
                              let rhs = UdpStream::connect(SocketAddr::new(IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1)), 53)).await.unwrap();
                              tokio::spawn(async move {
                                 copy_from_lhs_to_rhs(udp,rhs).await;
                              });	
			}
		}
	}
}

We also suggest that you take a look at the complete examples.