值得一看可能需要的修复或功能原始 payload 不含 superseded_by 标记。因此升级建议采用本期最终提交,以包含全部分阶段 Tunnel 变更,并避开明显不完整的中间 build 2.4.16768。
Tunnel 会话改用不可预测编号,并支持按需接入 socket
Tunnel 用户面对本期最主要的变化:TTunnelRelay 现在分配不可预测的会话标识符,TTunnelLocal 则新增事件驱动的 handshake 等待,并可接管已连接的 socket。本批次还增强了 Tunnel 缓存、临时会话清理及异步服务器在并发或重复 Shutdown 时的安全性。Delphi 10–10.3 与 FPC 用户获得了针对编译器、构建及线程析构的修正。
要点
- TTunnelRelay 会话 ID 不再使用可预测的 NetRandom32,而是由 Random128 经 Random9Digits 生成。
- TTunnelLocal 新增 WaitForHandshake 与 OpenSocket 以支持按需转发;应使用 build 2.4.16776,不要停在不完整的 build 2.4.16768。
- Tunnel 缓存刷新、临时会话清理及异步服务器 Shutdown 路径现在会阻止并发或重复执行。
- Delphi 10–10.3 绕过已知的指针表达式与内联编译器缺陷,FPC POSIX 的线程析构则避免不必要的 100 ms 等待。
升级建议
Tunnel 与异步服务器部署应将 build 2.4.16776 作为完整更新采用。不要停在 build 2.4.16768:其中已有 TTunnelLocal.WaitForHandshake 实现,但其类声明要到下一 build 才加入。Delphi 10–10.3 用户也应采用本期最终版本以获得编译器规避措施。
22 条中的 22 条 · 上游 23 次提交
1
高
Handshake 等待改为事件驱动,但此中间 build 并不完整
TTunnelLocal 新增 fHandshakeEvent 及 WaitForHandshake 实现:它在 fSendSafe 下检查 queue,通过 TSynEvent 等待而不消费帧,校验 session trailer,并在 ClosePort 时唤醒。但此修订中方法实现已存在,TTunnelLocal 声明尚未加入;声明在 c38c36d 才出现。
破坏性变更interp
mormot.net.tunnel
d2419079+63-5
net: new TTunnelLocal.WaitForHandshake method
影响
事件设计消除了轮询并保留提前到达的通知,但 build 2.4.16768 不是有效落点,因为类方法先实现后声明。build 2.4.16769 才补全公开类接口。
值得一看
不要固定在 build 2.4.16768;请使用 build 2.4.16776,以包含方法声明及后续关闭路径修复。
2
高
Tunnel 会话分配不再使用可预测 PRNG
mormot.net.tunnel 的 TTunnelRelay.PrepareNewSession 用 Random128 派生值替代 NetRandom32 shr 4。它最多检查三个 32-bit word 以得到非零候选值,在 fConsoleSafe 下保留原有冲突检查,并清除临时随机 buffer。
安全
mormot.net.tunnel
34791460+13-6
net: fixed TTunnelRelay.PrepareNewSession number predicability
影响
relay 不再从明确属于非加密序列的 NetRandom32 发放会话标识符。直接可预测性被消除,同时 TTunnelSession 大小及 relay service 签名不变;diff 并未证明完整的会话劫持利用链。
建议升级
凡 TTunnelRelay 暴露在完全可信边界之外,都应升级,并采用 build 2.4.16776 以获得最终 Random9Digits 实现。
公开 API
TTunnelRelay.PrepareNewSessionbehaviour-changed — 会话标识符现在来自 Random128,而非 NetRandom32。
3
高
异步服务器重复 Shutdown 不再重入清理流程
mormot.core.threads 的 TLoggedThread 新增三个受保护 byte flag。TAsyncConnections.Shutdown 与两个 backend 的 TAsyncServer.Shutdown 使用独立 flag 忽略重复调用;THttpAsyncServer.DoExecute 在 fShutdownInProgress 置位时也会退出。
修复
mormot.core.threads+1
93b26a97+16-5
net: fixed nested Shutdown calls of async servers
影响
析构与显式 Shutdown 路径无法再对同一实例重复执行 IOCP unsubscribe、socket 终止或 accept 释放。这降低了 Delphi 与 FPC 异步 HTTP/WebSocket 服务器的关闭竞争和重复清理风险。
建议升级
若异步服务器的多个所有权层可能在析构前调用 Shutdown,请升级并测试启动-停止循环及启动失败后的清理。
4
中
每秒 Tunnel 信息缓存现在仅由一个线程刷新
尽管 commit 标题互换,此 diff 实际修改 mormot.net.tunnel 的 TTunnelList.GetAllInfo。对 fInfoCacheTix32 使用 LockedExc32,选出一个调用方构建当前秒 snapshot;其他调用方在 fInfoCacheSafe 下复制 fInfoCache。
修复
mormot.net.tunnel
d1512dde+26-25
net: made TTunnelList.PurgeTransient atomic
影响
并发监控请求不再同时重建并竞争发布同一 TunnelInfo snapshot。应用 API 不变;relay 状态采集每秒只执行一次 callback 遍历。
建议升级
若 relay 并发调用 GetAllInfo,或向多个监控客户端公开 ConsolesInfo,请升级。
5
中
临时 Tunnel 清理现在由一个原子周期执行者负责
尽管标题互换,此 diff 实际修改 TTunnelList.PurgeTransient。LockedExc32 在取得 fSafe 前原子认领每个 16 秒清理周期;超时比较改为可安全处理计数回绕的减法;仅在确实移除 Tunnel 时才使 fInfoCacheTix32 失效。
修复
mormot.net.tunnel
1915e014+14-14
net: made TTunnelList.GetAllInfo cache atomic
影响
并发调用方无法重复执行同一清理周期,长时间运行也不会在 cardinal 回绕边界破坏超时判断。Relay 清理减少锁操作,并避免重复释放 callback。
建议升级
存在并发会话维护或超长运行时间的 relay service 应采用此修复。
6
中
关闭帧现在会唤醒并停止仍在 handshake 的 Tunnel
mormot.net.tunnel 的 TTunnelLocal.TunnelSend 在 fHandshake 仍存在时识别仅含 session 的关闭帧。它设置 fClosePortNotified、触发 fHandshakeEvent、标记 fClosed 并退出,不再将空帧推入 handshake queue。
修复
mormot.net.tunnel
9609945c+12-2
net: fixed TTunnelLocal early shutdown
影响
若远端在初始化完成前关闭,WaitForHandshake 可立即返回。延迟 Tunnel 不再把关闭通知误当作 handshake 数据,也无需等待超时。
建议升级
请随 build 2.4.16776 的完整 WaitForHandshake/OpenSocket 系列采用此修复,并测试初始化期间对端关闭。
7
中
WebSocket 帧日志不再无条件重置远程日志状态
mormot.net.ws.core 的 TWebSocketProcess.Log 现在仅在 DisableRemoteLog 参数为 true 时,才在写入帧前后调用 TSynLog.DisableRemoteLog。SendFrame 调用点也明确标出该 true 参数。
修复
mormot.net.ws.core
72c81483+7-5
net: fixed TWebSocketProcess.Log() code
影响
接收侧或其他以 DisableRemoteLog=false 调用的日志不再强制 logger 恢复为远程启用状态。SendFrame 仍会在自身 trace 前后抑制远程转发,以避免 WebSocket 日志递归。
值得一看
若 WebSocketLog 转发到远程 sink,请验证收发 trace 现在能保持预期的远程日志抑制状态。
8
中
ECDHE 初始化失败现在抛出明确的 Tunnel 异常
mormot.net.tunnel 的 TTunnelLocal.OpenInternal 将 Ecc256r1SharedSecret 失败后的静默退出改为 ETunnel.RaiseUtf8。异常会标识 TTunnelLocal 并包含本地端口。
修复
mormot.net.tunnel
8d1d4fc7+4-3
net: another Tunnel logic improvement
影响
无效的对端 ECDHE 公钥现在产生明确失败,不再得到含糊的零值式 Open 结果。故意输入畸形 handshake 的调用方应预期此路径抛出 ETunnel。
值得一看
若不可信对端可提供 handshake key,请检查 TTunnelLocal.Open 与 OpenSocket 周围的异常处理。
公开 API
TTunnelLocal.Openbehaviour-changed — Ecc256r1SharedSecret 失败现在抛出 ETunnel,而非静默退出。
9
中
应用现在可把已连接 socket 交给 TTunnelLocal
mormot.net.tunnel 公开 TTunnelLocal.WaitForHandshake 并新增 TTunnelLocal.OpenSocket。OpenSocket 校验非 nil socket 与端口,通过清空调用方变量转移所有权,并经受保护的 OpenInternal 与 Open 共用 handshake 初始化。ITunnelOpen 文档现在描述类似 SSH -R 的按需流程。
新功能
mormot.net.tunnel
c38c36da+158-44
net: introduced late access to the local Tunnel socket
影响
VNC 等反向转发可延迟 backend 连接,直到真实本地客户端到达。现有 Open 调用的源码契约不变;OpenSocket 成功调用后,调用方不得关闭或复用 Socket,因为所有权已转移给 TTunnelLocal。
值得一看
在以按需转发替代现有 Open 流程前,请测试 socket 所有权、双向 handshake、超时及对端关闭路径。
公开 API
TTunnelLocal.WaitForHandshakeadded — 等待首个已排队的对端 handshake,但不消费它。TTunnelLocal.OpenSocketadded — 在已连接 TNetSocket 上启动 Tunnel 并接管其所有权。
10
中
统一 helper 现在生成所有不可预测的九位会话编号
mormot.crypt.core 新增公开函数 Random9Digits。它从 Random128 取得三个 cardinal 候选值,清除临时 128-bit buffer,并返回 100000000..999999999;仅当所有候选均为零时返回零。mormot.net.tunnel 的 TTunnelRelay.PrepareNewSession 现在调用此 helper。
新功能
mormot.crypt.core+1
da7e1c2f+23-11
crypt: new Random9Digits() function
影响
Tunnel 会话标识符仍保持 32-bit 传输表示,但现在始终为九位十进制数并使用框架 CSPRNG。其他 Delphi/FPC 代码也可在适合该范围及零表示失败的契约时复用此 helper。
建议升级
Tunnel relay 用户应采用 build 2.4.16776,以同时获得不可预测分配及最终范围 helper。
公开 API
Random9Digitsadded — 返回 100000000..999999999 范围内不可预测的 cardinal;Random128 不可用时返回零。
11
中
Delphi 10–10.3 获得针对指针与内联的规避措施
mormot.defines.inc 为 compiler version 30 到 33 定义 ISDELPHI10_103。mormot.core.buffers 在该范围禁用 FromVarInt32 的 inline;mormot.core.base 将 AppendShortCurr64 中的类型化指针转换从 @p[index] 改写为这些编译器可接受的 pointer arithmetic。
编译器与平台
mormot.core.base+1
92d840ee+10-6
core: circumvent Delphi 10.x compiler bugs
影响
使用 Delphi 10、10.1、10.2 或 10.3 编译的项目可绕过 variable-integer 解码及 Currency 文本格式化中的已知编译器故障。生成行为预期不变;FPC 与其他 Delphi 版本不使用新条件。
建议升级
Delphi 10–10.3 团队应使用 build 2.4.16776 重建受影响 target,并重新运行序列化及 Currency 格式化测试。
12
低
TNetAddr 识别完整 IPv4 loopback 网段及 IPv6 ::1
mormot.net.sock 新增公开方法 TNetAddr.IsLoopback。任何首字节为 127 的 AF_INET 地址及 AF_INET6 的 ::1 字节模式返回 true;其他或未定义地址族返回 false。
新功能
mormot.net.sock
be380064+20-2
net: new TNetAddr.IsLoopback method
影响
网络代码现在可执行一次感知地址族的本地地址检查,而不再只比较 127.0.0.1。现有调用方不受影响;后续 commit 的 Tunnel accept 路径会采用此 helper。
公开 API
TNetAddr.IsLoopbackadded — 对 127.x.x.x 与 ::1 地址返回 true。
13
低
CheckHash 现在同时接受原始 buffer 与托管字符串
mormot.core.test 新增接收 data: pointer 与 len: PtrInt 的 TSynTestCase.CheckHash overload。现有 RawByteString overload 委托给它,共享实现计算 Hash32(data, len) 后生成诊断断言。
新功能
mormot.core.test
3ad5bbe2+13-4
core: new TSynTestCase.CheckHash() overload
影响
测试可直接验证 stream、short string 及任意 memory,无需先分配 RawByteString。该新增位于测试单元,因此生产运行时行为不受影响。
公开 API
TSynTestCase.CheckHash(pointer, PtrInt, cardinal, RawUtf8)added — 新增 overload 对显式 memory buffer 与长度计算 hash。
14
低
Relay 扫描与缓存信息复制改用更紧凑的指针循环
mormot.net.tunnel 引入 PTunnelRelayConsole,并将 HasConsolePrepared 与 ConsolesInfo 改写为递增 record pointer。TTunnelList.GetAllInfo 也移除短小锁保护赋值周围的 try/finally,同时保持相同锁与退出行为。
性能
mormot.net.tunnel
89996223+28-28
net: slightly optimized TTunnelRelay process
影响
Relay 元数据枚举减少了索引计算与异常框架开销。公开结果及锁语义保持不变,因此 Delphi/FPC 应用无需修改。
15
低
FPC POSIX 线程析构尽可能避开 RTL 固定等待
TThreadAbstract 仅在 FPCPOSIX 下重写 Destroy。主线程释放活跃且未挂起的线程时,会调用 Terminate,并在调用继承析构前通过 CheckSynchronize 与 SleepHiRes 短暂循环,直到 Finished 或 100 ms。
性能
mormot.core.threads
efc0950e+28-2
core: override TThreadAbstract.Destroy on FPC POSIX
影响
短生命周期 FPC POSIX 线程对象可在继承 RTL 路径施加通常的 100 ms WaitFor 延迟前完成。Delphi 与 Windows 不会编译此重写。
公开 API
TThreadAbstract.Destroybehaviour-changed — 在 FPC POSIX 上,活跃线程在继承析构前会先执行有界协作结束循环。
16
低
内部 INI section matcher 改用适配 Delphi 10 的循环
mormot.core.fmt 的 IdemPChar2 从带临时 AnsiChar 的 repeat loop 改写为 while loop,直接比较 table[up[PtrUInt(p)]],仅在匹配时递增 up。
编译器与平台
mormot.core.fmt
00f6828c+12-13
core: refactored INI parsing for Delphi 10.x
影响
INI section 名称的大小写归一化匹配行为不变,同时避开 Delphi 10.x 有问题的代码形式。FPC 与较新 Delphi 的应用 API 不变。
17
低
Windows Canary build 获得最新桌面与服务器版本标签
mormot.core.os 更新 build 查找表:桌面 build 29570 映射到 Windows 11 27H2,桌面 build 26300 仍映射 26H2,服务器 build 29651 映射到 Windows Server 26H2。Delphi 测试 batch 还为配置的非默认编译器启用优化与 NO_UI。
编译器与平台
mormot.core.os
61a6fc1b+12-9
core: detect Windows 11 27H2 and Windows Server 26H2 canary versions
影响
OSVersionText 可在这些 preview build 上报告预期标签,而非回退到较旧类别。运行时功能选择不变,因为此 diff 仅调整描述性查找表。
18
低
FPC Windows 命令行测试明确禁用 UI 单元
test/build_fpc.sh 为 win* target 添加 -dNO_UI,test/build_winarm.bat 为 aarch64-win64 添加同一 define。这样在未配置 widgetset path 时,mormot2tests 不再要求 Lazarus Interfaces 与 test.ui.pdf。
编译器与平台
55d28b7f+4-2
tests: define NO_UI in the command line FPC build scripts
影响
仓库的命令行测试构建可再次在无 LCL 的 FPC Windows 与 aarch64-win64 上工作。Lazarus package build 仍保留 UI 覆盖,应用构建 flag 不变。
19
低
延迟 Tunnel 增加直连与 WebSocket 端到端覆盖
test.net.proto 新增 TunnelDeferred。测试先准备 relay 两端,在连接 backend 前接受 viewer socket,等待 handshake,双向交换 VNC 风格 banner,并通过 WebSockets 上的 SOA callback 重复该流程。
测试
e22ca7df+186-2
tests: cover deferred Tunnel connection
影响
应用代码不受影响。新的按需 TTunnelLocal 路径现在既测试无传输序列化场景,也测试真实 WebSocket callback 路径。
20
低
Lazarus 测试项目登记十种预期异常类
test/mormot2tests.lpi 在 Lazarus 调试器配置中登记十个异常类名,包括 EHttpSocket、EYamlException、EStreamError 与 EJsonObjectDecoder。
测试
1b9767fa+34-2
test: ease mormot2tests debugging by registering some exceptions
影响
此变更仅影响 Lazarus 测试项目的调试器处理。框架代码、非调试测试行为及应用构建均不变。
21
低
回归 hash 现在统一报告预期值与实际值
四个测试单元将直接 Hash32 比较替换为 TSynTestCase.CheckHash。pointer-length buffer、序列化 variant、SOA JSON 及生成的 PDF memory 现在使用同一诊断断言,PDF 常量改写为十六进制。
测试
07032883+14-14
tests: use new CheckHash()
影响
回归测试失败时会给出更清晰的 hash 诊断,尤其适用于 PDF 字体嵌入因系统而异的情况。框架运行时与应用代码不变。
22
低
Loopback 检查改用共享地址 helper 与常量
mormot.net.sock 将两处 cLocalhost 文本用法替换为 IP4local。mormot.net.tunnel 的 TTunnelLocalThread.DoExecute 使用 TNetAddr.IsLoopback,不再只比较 fClientAddr.IP4 与 cLocalhost32。
杂项
mormot.net.sock+1
0ce4b076+5-5
net: minor loopback definitions usage
影响
本地 Tunnel 接入现在遵循共享的 IPv4 与 IPv6 loopback 定义,因此 ::1 会被视为本地地址。现有 IPv4 localhost 行为不变。