参考 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"
- unix server 第一次收到的数据是
Eth header + IP header + TCP header + "GET /index.html HTTP/1.1\r\n"
。
- 依次调用 Eth decoder + IP decoder + TCP decoder + HTTP decoder 进行解析,http decoder 不能完成解析,decoder 返回 Ok(None()) 表示 data 未消费。
- 此时第一次收到的数据
Eth header + IP header + TCP header + "GET /index.html HTTP/1.1\r\n"
被异步 I/O 缓存。
- unix server 第二次收到的数据是
Eth header + IP header + TCP header + "Host: www.test.com\r\n\r\n"
。
- 此时异步 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"
。
- 此时 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 的场景中使用?