5个版本

0.2.0-alpha.32024年5月25日
0.2.0-alpha.22024年5月19日
0.1.1 2024年5月9日
0.1.0 2024年5月5日

#1323 in 网络编程

Apache-2.0

68KB
1.5K SLoC

l3_extract

从第3层提取第4层连接

这个crate旨在提供一种方法,允许用户操作从第3层协议数据包获取的TCP和UDP,就像正常的异步TCP流和异步UDP套接字一样,但基于完整模式。

这个crate基于smoltcp,这是一个单线程、串行和事件驱动的用户空间TCP网络堆栈crate,但这个crate允许用户并发地使用TcpStreamUdpSocket和其他。

注意

这个crate试图将易用性放在首位,然后是性能,因此它绝对比内核TCP网络堆栈慢,也可能比使用smoltcp和手动编写的事件循环慢。

示例

use std::future::ready;
use std::net::Ipv4Addr;
use std::os::fd::OwnedFd;
use std::str::FromStr;
use futures_util::{AsyncRead, AsyncWrite, StreamExt, TryStreamExt};
use futures_util::stream::FuturesUnordered;
use futures_util::task::SpawnExt;
use l3_extract::{EventGenerator, Ipv4Cidr, TcpStack};
use futures_timer::Delay;

#[derive(Default)]
struct MyTimer;

impl Timer for MyTimer {
    async fn sleep(&mut self, dur: Duration) {
        Delay::new(dur).await
    }
}

async fn run() {
    let connection = create_layer3_connection();
    let (mut tcp_stack, event_generator, mut tcp_acceptor, mut udp_acceptor) = TcpStack::builder()
        .ipv4_addr(Ipv4Cidr::from_str("192.168.100.10/24").unwrap())
        .ipv4_gateway(Ipv4Addr::new(192, 168, 100, 1))
        .build()
        .unwrap();
    drive_tcp_stack(tcp_stack, connection);
    let mut futs = FuturesUnordered::new();
    futs.spawn(async {
        handle_events(event_generator).await
    }).unwrap();
    futs.spawn(async {
        let tcp_stream = tcp_acceptor.try_next().await.unwrap().unwrap();
        // do something with tcp_stream
    }).unwrap();
    futs.spawn(async {
        let udp_socket = udp_acceptor.try_next().await.unwrap().unwrap();
        // do something with udp_socket
    }).unwrap();

    futs.for_each(|_| ready(())).await;
}

async fn create_layer3_connection() -> OwnedFd {
    // create a layer3 connection
}

async fn handle_events(event_generator: EventGenerator) {
    // handle events
}

async fn drive_tcp_stack(tcp_stack: TcpStack, fd: OwnedFd) {
    // drive tcp stack on your way, such as spawn a background thread
}

依赖项

~6.5MB
~137K SLoC