3 个不稳定版本

新版本 0.7.0 2024年8月25日
0.7.0-alpha.22024年8月16日
0.7.0-alpha.12024年7月30日
0.6.0 2024年7月30日

#466游戏开发

Download history 222/week @ 2024-07-27 13/week @ 2024-08-03 59/week @ 2024-08-10 61/week @ 2024-08-17

每月下载量:355
aeronet_webtransport 中使用

MIT/Apache 协议

235KB
3.5K SLoC

aeronet_proto

crates.io docs.rs

为aeronet传输提供协议级功能实现。

由于不是所有底层传输都会提供相同的功能保证,这个crate提供了一些对底层协议无关的、无I/O的特定功能实现。

功能

功能 描述 aeronet_proto
缓冲 将小的消息合并成一个大的数据包(类似于Nagle算法)
分片 大消息使用多个数据包发送
通道管理 消息可以通过不同的通道发送,并具有不同的保证
可靠性 可靠发送的消息将确保被对端接收到
排序 接收到的消息将以发送时的顺序接收
帧定界 API维护消息边界(即不仅仅是一串字节流) -
加密 未经授权的第三方无法读取传输中的网络数据 -
身份验证 只有被授权使用此应用的用户才能连接 -
验证 消息在传输过程中没有被篡改或损坏 -
拥塞控制 控制数据发送的速度,以避免网络拥塞 -
协商 确保在对话之前两个对端都在使用相同的协议 -

客户端始终作为发起者,发送第一条消息。

未标记为该crate提供的功能必须在传输实现级别实现。例如,WebTransport默认加密连接,因此在aeronet_proto级别实现加密是没有意义的。

如果传输已经支持协议提供的功能,建议使用协议的实现,因为这样可以使API在不同传输实现之间更加一致。例如,QUIC/WebTransport通过其流机制提供可靠性和排序,但是这些不支持与aeronet_proto完全相同的特征集,因此不使用。

可视化工具

功能标志:visualizer

可视化器是一个集成在crate中的调试工具,它使用eguiegui_plot来显示网络统计数据的图表。它与任何使用Session(参见SessionBacked)的客户端传输兼容,也可以在Bevy中使用。

有关如何使用可视化器的说明,请参阅SessionStatsVisualizer

协议

该协议主要受Building a Game Network Protocol的启发,在术语和实现方面进行了一些调整。

术语

  • 对等体:可以参与连接、发送或接收数据的实体。
  • 消息:用户提供的字节缓冲区,用户希望将其发送给对等体。这是通过aeronet-Transport traits公开的最低级别的API类型。
  • 数据包:可以作为一个单独的整体发送或接收的字节缓冲区。这是使用aeronet协议的实现必须关注的最低级别的API类型。
  • 连接:用于在两个对等体之间传输原始数据字节的基础网络连接
  • 会话Session - 可以在连接上发送数据的同时使用在功能中概述的功能,例如分段、可靠性、排序

要求

aeronet协议可以在几乎所有传输之上使用。要求如下:

  • 传输必须能够在对等体之间发送数据包,其中数据包定义为字节的可变长度序列
  • 在传输后,数据包必须保证具有相同的 内容,而不会被截断或扩展
  • 不需要保证可靠性、顺序或去重

布局

有关编码数据包布局的完整说明,请参阅[ty]。

会话

API的入口点是Session,它管理传入和传出消息,而无需执行任何I/O。可以使用Session::clientSession::server创建一个会话,并提供一个配置,该配置确定参数,例如最大数据包长度、发送/接收通道以及每秒可以发送多少字节。

API公开了以下主要功能:

  • Session::send用于将消息缓冲起来以供稍后发送
  • Session::flush用于构建现在应发送的数据包
  • Session::recv用于接收传入的数据包并读取其数据
  • Session::update 用于更新会话的内部状态,并检查我们是否使用了过多的内存(参见 内存管理

内存管理

如果我们不限制会话使用的最大内存量,恶意节点可能会通过耗尽我们的所有内存来导致服务拒绝。因此,我们定义会话可以使用的最大内存量,并且如果使用过多内存,Session::update 将终止连接。

如果会话使用过多的内存

  • 对端发送许多消息片段,但这些片段永远不会收到它们的最终片段
    • 我们的端将被迫保留所有片段,直到它们完全重新组装
    • 理论上,我们可能会丢弃属于不可靠通道的片段(这可能在以后实现),但我们永远不允许丢弃通过可靠通道发送的片段
  • 对端永远不会确认我们的数据包
    • 我们的端将被迫永远保留可靠消息的片段,因为我们必须重新发送它们,直到对端确认

MTU

最大可传输单元,或MTU,定义了单个数据包可能有多大(以字节为单位)。如果数据包长度超过MTU,则网络路径上的路由器可能会丢弃该数据包。为了避免这种情况,会话将永远不会产生一个大于用户指定的MTU的数据包。大于MTU的消息将被拆分成较小的片段,并在接收端重新组装(带有一些额外的开销,用于数据包和片段头)。

在创建会话时,您定义一个最小MTU和一个初始MTU。片段永远不会大于 min_mtu - OVERHEAD,然而一个数据包永远不会大于 mtu(由于接收器逻辑的工作方式,在连接期间无法更改片段的大小)。

然而,MTU可能会在连接的生命周期内发生变化,并且当有更高的路径MTU可用时,我们可以利用它,当它不再可行时减少MTU。为此,会话允许您通过 Session::set_mtu 来更改MTU。MTU永远不会低于 min_mtu

模糊测试

为了确保协议代码在所有情况下都能正常工作,我们既使用了单元测试也使用了模糊测试。模糊测试必须在Rust nightly上运行(在命令行中添加 +nightly)。

要从 aeronet_proto/fuzz 目录启动模糊测试,请运行以下命令

cargo fuzz run <fuzz_target>

依赖关系

~4–13MB
~163K SLoC