网络流量处理中的协议解析六: 执行器

执行器

rust 中有很多异步执行环境。但是异步执行环境有一个问题。它有"传染性",如果一个函数是异步的,那么它的所有调用者都必须是异步的。在前面的流量处理模型并不是异步的。所以为了不至于把协议解析部分的异步影响到流量处理模型,我们需要一个自己的执行器。这个执行器把异步操作封装起来,然后在流量处理模型中使用。尽量不影响使用者的习惯和模型,是一个库的修养。

rust 的执行器简单来说类似于前文所讲的c语言的状态机驱动函数。如果一个future返回了 Ready ,说明future已经完成了,需要执行下一步。如果一个future返回了 Pending ,说明future还没有完成,需要等待下一次调用。因为我们不需要复杂的异步运行时,所以这里的执行器只需要控制好future的返回值即可。代码如下:

rust 复制代码
    let waker = dummy_waker();
    let mut context = Context::from_waker(&waker);
    match Pin::as_mut(parser).poll(&mut context) {
        Poll::Ready(Ok(())) => {
            self.c2s_state = TaskState::End;
            Some(Ok(()))
        }
        Poll::Ready(Err(())) => {
            self.c2s_state = TaskState::Error;
            Some(Err(()))
        }
        Poll::Pending => None,
    }

这样,内部是异步,外部是同步。每到来一个包,执行器就执行一次future,也就是解码器。外部不需要异步操作。也就是在同步代码中可以调用执行器:

rust 复制代码
    loop {
        pkt = get_packet();
        task.run(pkt);
    }

当然,要获取解码结果。需要提前设置回调函数。解码过程中就会触发回调函数。

解码器

所有的这些工作,都是为了解码器。因为需要同时处理大量的链接,解码过程中是不能等待后续数据包的。所以解码器是一个future,也就是异步函数。当后续数据还没有到来时,解码器返回Pending,暂时挂起。执行器得到Pending后,不会认为这个链接的解码已经结束,而是继续处理下一个链接。

但这种异步调用的复杂性都被rust的future机制封装起来了,解码器的实现关注解码器的实现即可。完全可以按照同步的模式来写,例如SMTP协议的解码器的部分代码:

rust 复制代码
    loop {
        let (line, seq) = stm.readline_str().await?;

        if line == "\r\n" {
            return Ok((boundary, te));
        }
    }

这就是读取重组后的头部数据的过程。可以看到,它并没有关心数据没有到来的情况。如果当前的数据包并没有完整的数据,解码器中也不需要对此进行判断,和退出。它完全按照同步的过程在执行解码。直到读取到头结束为止。唯一的区别就是它的读取数据函数式一个异步函数。末尾加了await关键字。

每一个await都会触发一次future的调用。如果当前的数据包没有完整的数据,那么await会返回Pending,解码器会被挂起。执行器会继续处理下一个数据包。当数据包到来时,解码器会被唤醒,继续执行。直到读取到头结束为止。

这样,我们就可以把协议解析的工作交给执行器来处理。执行器会自动处理异步的情况。使用者只需要关注解码器的实现即可。而且解码器的过程变得简单容易理解。

从最开始的c语言中的大循环中记录状态,到c语言中用状态机驱动,再到rust的future机制,再到现在的解码器,过程越来越简单,最终我们以同步的流水账式的代码来实现了异步的解码过程。

参考: protolens@gitee protolens@github

相关推荐
知道了啊3 小时前
websocket和SSE学习记录
websocket·网络协议·学习
EasyDSS6 小时前
视频监控EasyCVR视频汇聚平台接入海康监控摄像头如何配置http监听功能?
大数据·网络·网络协议·音视频
九州ip动态6 小时前
避免IP地址关联,多个手机设备的完美公网IP问题
网络协议·tcp/ip·智能手机
DanmF--7 小时前
详解与HTTP服务器相关操作
服务器·网络·网络协议·http·unity·c#
Harry小哥哥8 小时前
企业网站安装 SSL安装的必要性
网络·网络协议·ssl
2501_915909069 小时前
安卓APP-HTTPS抓包Frida Hook教程
websocket·网络协议·tcp/ip·http·网络安全·https·udp
Hello.Reader11 小时前
Mitmproxy 11 发布 —— 完整支持 HTTP/3!
网络·网络协议·http
Andrew121911 小时前
TCP常见知识点整理
网络协议·tcp/ip
5172 天前
网络编程(UDP)
网络·网络协议·udp