参考 mini-lust/tutorials,我熟悉了异步 I/O tokio_util::codec::Decoder 的使用,但是想在 DPI 项目中使用它,便产生了下述疑问,希望您能帮我解惑 **Decoder 在 L7 Application Server 中如何使用** 当收到 data 时,调用 decoder 进行解析: * 如果 data 的数据足够长,decoder 可以完成解析,decoder 返回 Ok(Some()) 表示 data 被消费 * 如果 data 的数据不够多,decoder 不能完成解析,decoder 返回 Ok(None()) 表示 data 未消费 (此时 data 由异步 I/O 缓存,等下次再有数据到来时,两次的数据拼接到一起再调用 decoder) 这种处理模式在 L7 Application 的实现中是很 easy 的。 **Decoder 在 DPI 中如何使用** 当我们收到的 data 是 Eth frame 时就出现问题了 (例如 unix socket server 模拟 DPI 的应用场景) 例如 unix client 将 http request 分两个 Eth frame 发送出去: - 第一次发送的数据为:`Eth header + IP header + TCP header + "GET /index.html HTTP/1.1\r\n"` - 第二次发送的数据为:`Eth header + IP header + TCP header + "Host: www.test.com\r\n\r\n"` 1. unix server 第一次收到的数据是 `Eth header + IP header + TCP header + "GET /index.html HTTP/1.1\r\n"`。 2. 依次调用 Eth decoder + IP decoder + TCP decoder + HTTP decoder 进行解析,http decoder 不能完成解析,decoder 返回 Ok(None()) 表示 data 未消费。 3. 此时第一次收到的数据 `Eth header + IP header + TCP header + "GET /index.html HTTP/1.1\r\n"` 被异步 I/O 缓存。 4. unix server 第二次收到的数据是 `Eth header + IP header + TCP header + "Host: www.test.com\r\n\r\n"`。 5. 此时异步 I/O 缓存中的数据为 `Eth header + IP header + TCP header + "GET /index.html HTTP/1.1\r\n"` 和 `Eth header + IP header + TCP header + "Host: www.test.com\r\n\r\n"`。 6. 此时 decoder 调用关系混乱,如果 IP header 再实现 IP 分片重组,TCP 乱序重组,decoder 的调用更加复杂,那么异步 I/O 是否适合在 DPI 的场景中使用? 参考 Rust 的 DPI 开源项目 sniffglue 和 pcap-analyzer * https://github.com/kpcyrd/sniffglue * https://github.com/rusticata/pcap-analyzer 发现 sniffglue 和 pcap-analyzer 的实现中都没有使用异步 I/O,异步 I/O 是否适合在 DPI 的场景中使用?