路线图
当前状态:1.1.3 已发布
最新是 1.1.3:Windows 客户端的安装程序和安卓客户端的 APK 可以从 Releases 下载, 装着旧版本的客户端打开时会问要不要更新。 还没经过安全审查,Windows 安装程序没有代码签名。
真实环境里验证到哪一步,如实写在这里:
| 验证过的 | 还没验证的 |
|---|---|
| Windows 客户端、安装程序装在真的电脑上用过;在一台 Windows 11 上实测连通过 | 两台真的电脑之间拿真的游戏联机 |
| 安卓客户端装在真的手机上跑过;CI 的安卓模拟器每次打包都经官方服务器真的连一次网 | 拿手机游戏和电脑联机 |
| 直连模式在真实网络里打通过:两台安卓手机都用移动流量(对称型的运营商级 NAT),经公网 IPv6 直连上。之前在家用宽带之间没通,查出并修了安卓 17 的局域网权限、IPv6 用错源地址 | 家用宽带之间、电脑和手机之间的直连(修完之后还没再测);两边都只有 IPv4 时 |
| 经协调服务的打洞、中继:Linux 上模拟的 NAT、CI 里每次提交都跑 | 真实的家用路由器、运营商 NAT 之间打洞 |
下面每一项后面的状态标记是真实的:
| 标记 | 含义 |
|---|---|
| 设计中 | 在讨论方案,还没动代码 |
| 开发中 | 有代码在写,还没发版本 |
| 已发布 | 发了版本、可以下载,但还没在真实环境里验证过 |
| 真机上跑过 | 装在真的电脑或手机上用过,但还没在真实的联机场景里验证 |
| 可用 | 能跑,有人在真实场景里用 |
截至今天,没有任何一项达到「可用」。
1.1.3
用 Glassium 1.1.3。
| 项目 | 状态 |
|---|---|
| 手机和电脑一样的液态玻璃:不模糊的玻璃,边上折射、色散(CSS 玻璃的 SVG 位移滤镜);弹窗里的玻璃也是 | 已发布 |
| 手机上网络页不再一直被拖慢:连线上的光点不再每帧重绘整张图 | 已发布 |
| 切回网络页时节点不再在错的位置待一秒(手机上也不再能横向滚动) | 已发布 |
| 底部导航连点卡住:去掉手机上大面积的磨砂、透镜画布降到 2 倍像素 | 已发布(真机待验证) |
| 官网有了网站图标 | 已发布 |
1.1.2
用 Glassium 1.1.2。
| 项目 | 状态 |
|---|---|
| 启动不再卡:以前启动动画画 Logo 时会停顿半秒(玻璃的着色器同步编译),之后每秒卡一下 | 已发布 |
| 鼠标在窗口里移动时不再掉帧:背景点阵只重画指针附近那一块 | 已发布 |
| 按钮、头像、网状图的节点、连线上的延迟、输入框都是液态玻璃;网状图的节点、头像是无色的透明玻璃,颜色留在描边上 | 已发布 |
| 弹窗(以及手机上)用 CSS 画的玻璃也有液态玻璃的边:边上的光带、红蓝色边、顶上的高光 | 已发布 |
| 直连诊断写明"对方没有 IPv6",对称型 NAT 时的说法改对 | 已发布 |
1.1.1
版本号从这一版起与 Glassium 同步(这一版用 Glassium 1.1.1)。
| 项目 | 状态 |
|---|---|
| 直连:正在用的直连断了、本机换了网络时,重新密集打一轮洞 | 已发布 |
| 直连:没打通时朋友卡片上写明最可能的原因和怎么办,诊断里列出全部 | 已发布 |
| 直连:认得的地址还没通、对方从那里打过来时马上回探(真机上撞过:对方的报文到了,过了 29 秒才通) | 已发布 |
| 诊断日志:STUN 每轮只写一次、预测的端口只列前几个 | 已发布 |
| 手机上的朋友页改成一人一张卡片(以前是表格,在卡片里左右滑) | 已发布 |
| 电脑上的卡片、安装程序的面板换成液态玻璃:边缘把后面的点阵拉弯、带色散 | 已发布 |
| 手机底部的导航按住、拖动时是液态玻璃透镜:里面的字放大、边上压缩带色散 | 已发布 |
| 路线图、文档按真实进度重写 | 已发布 |
1.1.0
界面统一用 Glassium 1.1.0:弹窗、提示条、状态胶囊、手机底部的标签栏都是它的玻璃; 安卓上玻璃用 CSS 画(backend: 'css'),滑动时跟手。安装程序的动画一个接一个,不再叠在一起。 Glassium 1.1.0 里有几处是按 Meshora 的需要加的、修的。
1.0.1 – 1.0.5
1.0.0 之后的几个补丁版本:直连模式(1.0.2)和它的加强(局域网与公网 IPv6 候选、端口预测、UPnP / PCP / NAT-PMP、 连上之后互相告知新地址、按 IPv4 / IPv6 分开写的诊断)、安卓 17 的局域网权限(1.0.5)、打开时只查一次更新、 打开时不再加载两遍、窗口藏起来时不再刷新。每个版本改了什么见 Releases。
M0 地基
| 项目 | 状态 |
|---|---|
| 仓库、官网、设计文档 | 可用 |
| Rust workspace 与 crate 划分 | 可用 |
| 控制面 / 数据面接口契约 | 已发布 |
| 威胁模型 | 可用 |
- crate 划分已经定了,但还有几个 crate 没建,等各自有代码可写时再建, 见接口契约 · crate 划分。
- **接口契约**已经有了第一个实现(M1 的数据面)来检验它。 控制面后来也照着它写了,随 1.0 发布。
- **威胁模型**是初版,M1 实现时会逐条对照。
M1 打通主干
目标:两台 Windows 机器,一条加密隧道,能互相 ping 通。
| 项目 | 状态 |
|---|---|
| 节点身份与注册(公钥即身份,Noise IK 认证) | 已发布 |
| boringtun 集成 | 已发布 |
| wintun 虚拟网卡 | 已发布 |
| 控制面最小实现(发现 + 密钥分发) | 已发布 |
| 端点探测(类 STUN) | 已发布 |
| UDP 打洞协调 | 已发布 |
| Relay 回退 | 已发布 |
在 Linux 上用网络命名空间模拟机器和路由器,各跑一个 meshorad,用真的 ping 验证, 并检查两边最终选定的路径。CI 每次提交都跑:
| 场景 | 最终路径 |
|---|---|
| 两台机器在同一网段 | 直连 |
| 同一网段,但只允许走中继 | 中继 |
| 两边各在一个普通 NAT 后面(家用路由器的典型配置) | 打洞成功,直连 |
| 接着掐断两个 NAT 之间的 UDP | 几秒后回落中继(测试里约 8 秒) |
| 再恢复 | 几秒后切回直连(测试里 1 到 4 秒) |
| 一边的路由器换了公网地址(运营商重新分配) | 重连、重新探测、重新打洞,十来秒后回到直连 |
| 一边换了网络(本机地址、路由器、公网地址全变) | 立刻重连、重新探测、重新打洞,约 8 秒后回到直连;经中继的路也能恢复 |
| 一边在对称 NAT 后面(每个目标换一个外部端口) | 打洞不通,中继 |
还差的:
- Windows:CI 的 Windows 虚拟机上,真的
meshorad.exe建起 wintun 网卡,和同一台机器上的另一个节点 经加密隧道收发报文,直连和经中继都通。但还没在两台真的 Windows 机器之间试过 —— 这是 M1 目标里明写的 - 打洞:测试里的 NAT 是用 Linux 的 iptables 模拟的。真实网络里的家用路由器、运营商的 NAT 行为各异,还没验证过
- 回落要几秒:M1 里直连断了要 6.5 秒才算断。1.0.0 里缩短到了 2~3 秒,见下面的"换网络不掉线"
- 中继:协调服务可以给好几个中继,节点每个都经它探测延迟和丢包,挑通着的、明显更好的走; 正在用的中继挂了,两三秒内换到别的(1.0.0 加的,有端到端测试)。但另起的中继只认启动时给它的名单, 认不得凭邀请码加入的成员 —— 实际能用的第二个中继,目前只对名单里的节点有用
M1 的验收:两台 Windows 机器各跑一个 meshorad,经 Meshora 互相 ping 通 —— 能直连时走直连, 打不通洞时经中继。步骤和算通过的标准写在仓库 README 的「两台 Windows 机器:M1 的验收」一节,有两台 Windows 机器的话欢迎照着做一遍,把结果开 Issue 告诉我们。
这是整个项目最关键的里程碑。M1 跑通之前,其余全是纸面工作。
1.0.0 局域网联机
1.0.0 只做一件事:让不在一处的朋友能用局域网模式联机打游戏。 客户端有 Windows 和安卓。 为什么是这几项、每一项难在哪,见局域网联机:1.0.0 做什么。
| 项目 | 状态 |
|---|---|
| Virtual LAN(overlay 地址分配) | 已发布 |
| 广播 / 组播转发(让游戏的房间列表能看见对方) | 已发布 |
| 加入同一个网络的方式(一人建、朋友凭邀请加入) | 已发布 |
| ACL(谁能加入这个网络) | 已发布 |
| 延迟优先的选路(抖动权重高于平均延迟) | 已发布 |
| 换网络时游戏不掉线 | 已发布 |
| Windows 桌面客户端 | 真机上跑过 |
| 在客户端里建网络:官方服务器 / 本机当主机(UPnP)/ 我的服务器 | 已发布 |
一台服务器托管很多网络(meshora-coord --hub),谁都能建、有限额 | 已发布 |
| 网主在客户端里管网络(移出成员、换网络码、一次性和限时网络码、改名、解散) | 已发布 |
官方服务器(阿里云,39.108.210.40) | 在跑 |
| Windows 安装程序(自己写的液态玻璃安装程序) | 真机上跑过 |
| 安卓客户端(VpnService) | 真机上跑过 |
| 自动更新(签名的更新清单) | 已发布 |
| 不用服务器的直连模式(互发连接码、STUN、打洞,房主转发) | 真机上跑过:两台用移动流量的手机经 IPv6 打通 |
地址分配:凭邀请码加入的节点,协调服务自动分给它最小的空闲地址,存进状态文件,重启不变。 名单里的节点仍按顺序分配
换网络不掉线:正在用的直连每 2 秒探测一次,连丢两次就切到中继,从断开到切走大约 3~4 秒(M1 是 6.5 秒); 本机换了网络时旧的直连立刻作废、先走中继。有单元测试,还没在真实网络里量过
延迟优先的选路:每条直连记着平滑后的往返时间和抖动,按"往返时间 + 4 × 抖动 + 丢包罚分"选; 正在用的直连要别的路明显更好才换。中继那条路也探测,和直连放在一起比,但要明显更好才选它;从还通的直连换到中继,要中继连续半分钟都明显更好
加入网络:协调服务启动时打出网络码(
公钥@地址:端口#邀请码),朋友贴进客户端就能加入,不用重启协调服务。 还可以单独生成只能用几次、或者到时候就过期的邀请码(meshora-coord invite)谁能加入:名单(
--node)加上凭邀请码加入的成员。改状态文件就能移出人、换邀请码,不用重启: 被移出的节点马上断开、不再自动重连。还没有更细的规则(比如谁只能连谁)—— 联机网络里大家本来就是互通的桌面客户端:界面、设置、托盘、出错提示都有了,节点跑在客户端进程里,见桌面客户端。 在一台 Windows 11 上以管理员身份实测连通过(本机两个节点);还没在两台电脑之间试过
安装程序:自己写的(
crates/meshora-setup,和客户端同一套界面),CI 打出来,带核对过的wintun.dll, 装到 Program Files;能升级最早那个 1.0.0 的 NSIS 安装。界面在真实窗口里看过,还没在干净的系统上真的装、升级、卸载过,也没有代码签名建网络:客户端里选位置建好,拿到网络码发给朋友。有单元测试和端到端测试(在 hub 上建网、凭网络码加入、网主踢人、 两个网络互相看不见);对官方服务器跑过冒烟测试(
cargo test -p meshora-control --test e2e -- --ignored a_real_hub), 加上安卓模拟器那次(见下),端点探测(UDP 7443)和中继都验证过了。本机当主机的 UPnP 还没在真的路由器上试过安卓客户端:和 Windows 客户端同一套界面和节点代码,网卡由 VpnService 建,见安卓客户端。 CI 里每次都在模拟器上真的连一次:凭网络码加入建在官方服务器上的网络、回 ping。装在真手机上跑过: 安卓 17 要多申请"访问局域网"权限(1.0.5 加的),就是在真机上查出来的
自动更新:客户端查 Release 里的
latest.json,核对 Ed25519 签名(签的是平台、版本、哈希); Windows 上点一下装好再打开,安卓上交给浏览器下载。签名、版本比较有测试;整个流程要等下一个版本发出来才真的走一遍广播 / 组播转发是 1.0.0 里最关键的一项:没有它,互相 ping 得通,房间列表里却看不见对方。 数据面的转发已经写了、有单元测试;客户端默认压低虚拟网卡的跃点数,让 Windows 把游戏的广播交给它。 在一台 Windows 上实测过:受限广播、组播、网段广播都进了 Meshora、转发给了对方。 还没拿真的游戏在两台 Windows 之间试过(见局域网联机)
直连模式:没有服务器、也没有公网 IP 时,房主和每位朋友互发一段连接码,靠公共 STUN 问到公网地址、两边同时打洞, 见不用服务器(直连)。没有中继兜底,对称型 NAT 多半打不通。端到端测试在一台电脑上跑(本机的假 STUN、 三个节点、朋友之间经房主互通)。在真实网络里打通过:两台安卓手机都用移动流量, 公网 IPv4 是对称型的运营商级 NAT、打不通,经公网 IPv6 直连上(2026-10-08)。之前在家用宽带之间没通,查出的安卓 17 局域网权限、IPv6 用错源地址在 1.0.5 修了,家用宽带之间修完还没再测
1.0 之后
1.0.0 只做联机。下面这些是更长远的方向,1.0.0 之前一项都不做:
| 项目 | 状态 |
|---|---|
| Gateway(出口节点) | 设计中 |
| 能力声明与授权模型 | 设计中 |
| 按 IP / 端口分流 | 设计中 |
| 按域名分流(DNS 拦截) | 设计中 |
| 按进程分流(Windows WFP) | 设计中 |
| 通用组网(NAS、多地办公等非游戏场景的完整体验) | 设计中 |
| Windows、安卓以外的客户端(macOS、Linux 桌面、iOS) | 不做 |
下面两项的技术难点值得先写清楚,免得"配个规则就行"的错觉。
Gateway
技术实质:出口节点对应的 peer 配置里 AllowedIPs 设为 0.0.0.0/0(和 ::/0), 其余节点把默认路由指向它;网关侧开启 IP 转发并对出站流量做 NAT。
典型用途是出差时把流量绕回家里的网络,访问只对家庭宽带开放的服务。
需要注意的坑:
- DNS 必须跟着走,否则会在本地解析出错误的结果,还会泄漏查询记录
- 别把网关自己的流量绕进隧道,否则形成路由环路
- 网关节点需要管理员权限来改路由表和开启转发
Application Routing
技术实质:按应用、域名、IP、端口决定流量走哪条路径。这是所有方向里工程量最大的一项。
几种匹配维度的难度差得很远:
| 维度 | Windows 上怎么做 | 难度 |
|---|---|---|
| IP / 端口 | 路由表 + 防火墙规则 | 低 |
| 域名 | 拦截 DNS,把解析结果映射到策略 | 中 |
| 应用(进程) | WFP(Windows Filtering Platform),按 PID 关联流量 | 高 |
按进程分流必须走 WFP:在过滤层拿到每个连接的发起进程,再决定放行到哪条路径。 这需要一个 WFP callout 驱动或者用户态的 ALE 层过滤,实现和调试成本都不低。
按域名分流还有个绕不开的麻烦:DoH/DoT 把 DNS 加密了。 应用自带的加密 DNS 会绕过系统解析器,导致拦截失效。要么劫持并代答,要么接受这类流量落到默认策略。
平台
| 平台 | 状态 |
|---|---|
| Windows(wintun) | 真机上跑过 |
| 安卓(VpnService) | 真机上跑过 |
| Linux | 不做客户端;服务端只给官方服务器用,不发布 |
| macOS、iOS、OpenWrt | 不做 |
局域网联机的玩家绝大多数在 Windows 上,手机用来一起玩手游或者在外面连回去。其余平台的客户端不打算做。
开发时实测跑得最多的反而是 Linux:开发用的云端环境是 Linux,虚拟网卡和端到端测试在那里能真跑。 Windows 这边靠 CI 的 Windows 虚拟机:除了编译、lint、单元测试,还真的建 wintun 网卡、跑守护进程;安卓靠 CI 的模拟器。
没有时间表
这是个人项目,给不出交付日期,写一个出来也是骗人。