Worth a looka fix or feature you may wantThe raw payload contains no superseded_by markers. The landing recommendation therefore uses the edition head, which includes every staged tunnel change and avoids the visibly incomplete intermediate build 2.4.16768.
Tunnel sessions become unpredictable and demand-driven sockets arrive
Tunnel users get the largest changes: TTunnelRelay now allocates unpredictable session identifiers, while TTunnelLocal gains event-driven handshake waiting and ownership of an existing connected socket. The batch also makes tunnel caches, transient cleanup and asynchronous-server shutdown safer under concurrent or repeated calls. Delphi 10–10.3 and FPC users receive targeted compiler, build and thread-destruction corrections.
TL;DR
- TTunnelRelay session IDs now come from Random128 through Random9Digits instead of the predictable NetRandom32 generator.
- TTunnelLocal adds WaitForHandshake and OpenSocket for demand-driven forwarding; land on build 2.4.16776, not the incomplete build 2.4.16768.
- Tunnel cache refresh, transient purge and asynchronous-server Shutdown paths now reject competing or duplicate execution.
- Delphi 10–10.3 avoids known pointer-expression and inlining compiler bugs, while FPC POSIX thread destruction avoids an unnecessary 100 ms wait.
Upgrade advice
Tunnel and asynchronous-server deployments should take build 2.4.16776 as a complete set. Do not stop on build 2.4.16768: it contains the TTunnelLocal.WaitForHandshake implementation before its class declaration is added in the following build. Delphi 10–10.3 users should also take the head for the compiler workarounds.
22 of 22 entries · 23 commits upstream
1
High
Handshake waiting becomes event-driven, but this intermediate build is incomplete
TTunnelLocal gains fHandshakeEvent and an implementation of WaitForHandshake that checks the queue under fSendSafe, waits on TSynEvent without consuming the frame, validates the session trailer and wakes on ClosePort. In this revision the method implementation exists, but its declaration is not yet present in TTunnelLocal; that declaration arrives in c38c36d.
Breaking changesinterp
mormot.net.tunnel
d2419079+63-5
net: new TTunnelLocal.WaitForHandshake method
Impact
The event design removes polling and preserves an early notification, but build 2.4.16768 is not a valid stopping point because the class method is implemented before being declared. Build 2.4.16769 completes the public class surface.
Worth a look
Do not pin build 2.4.16768; use build 2.4.16776 so the declaration and later close-path fix are included.
Units
2
High
Tunnel session allocation stops using a predictable PRNG
TTunnelRelay.PrepareNewSession in mormot.net.tunnel replaces NetRandom32 shr 4 with values derived from Random128. It tests up to three 32-bit words for a non-zero candidate, keeps the existing collision checks under fConsoleSafe and clears the temporary random buffer.
Security
mormot.net.tunnel
34791460+13-6
net: fixed TTunnelRelay.PrepareNewSession number predicability
Impact
A relay no longer issues session identifiers from the explicitly non-cryptographic NetRandom32 sequence. This removes their straightforward predictability without changing TTunnelSession size or the relay service signatures; the diff does not establish a complete session-hijacking exploit.
Upgrade recommended
Upgrade any TTunnelRelay exposed beyond a fully trusted boundary, and take build 2.4.16776 for the finalized Random9Digits implementation.
Public API
TTunnelRelay.PrepareNewSessionbehaviour-changed — Session identifiers now come from Random128 rather than NetRandom32.
Units
3
High
Repeated asynchronous-server shutdown no longer re-enters cleanup
TLoggedThread in mormot.core.threads gains three protected byte flags. TAsyncConnections.Shutdown and both TAsyncServer.Shutdown backends use separate flags to return on duplicate calls, while THttpAsyncServer.DoExecute also exits when fShutdownInProgress is set.
Fixes
mormot.core.threads+1
93b26a97+16-5
net: fixed nested Shutdown calls of async servers
Impact
Destructor and explicit shutdown paths can no longer repeat IOCP unsubscribe, socket termination or accept-release work on the same instance. This reduces shutdown races and duplicate cleanup on Delphi and FPC asynchronous HTTP/WebSocket servers.
Upgrade recommended
Upgrade asynchronous server deployments whose ownership layers may call Shutdown before destruction, then exercise start-stop and failed-start cleanup tests.
4
Medium
Only one thread now refreshes the per-second tunnel information cache
Despite the swapped commit title, this diff changes TTunnelList.GetAllInfo in mormot.net.tunnel. LockedExc32 on fInfoCacheTix32 elects one caller to build the current-second snapshot; other callers copy fInfoCache under fInfoCacheSafe.
Fixes
mormot.net.tunnel
d1512dde+26-25
net: made TTunnelList.PurgeTransient atomic
Impact
Concurrent monitoring requests no longer rebuild and race to publish the same TunnelInfo snapshot. Application APIs are unchanged; relay status collection performs one callback pass per second.
Upgrade recommended
Upgrade relay processes that query GetAllInfo concurrently or expose ConsolesInfo to multiple monitoring clients.
Units
5
Medium
Transient tunnel cleanup now has one atomic periodic owner
Despite the swapped title, this diff changes TTunnelList.PurgeTransient. LockedExc32 atomically claims each 16-second purge interval before fSafe is acquired, timeout comparison becomes wrap-safe subtraction, and fInfoCacheTix32 is invalidated only when a tunnel was actually removed.
Fixes
mormot.net.tunnel
1915e014+14-14
net: made TTunnelList.GetAllInfo cache atomic
Impact
Concurrent callers cannot run the same purge cycle twice, and long uptimes do not break timeout detection at the cardinal wrap boundary. Relay cleanup does less locking and avoids duplicate callback release work.
Upgrade recommended
Take this fix for relay services with concurrent session maintenance or very long uptimes.
Units
6
Medium
A close frame now wakes and stops a tunnel still handshaking
TTunnelLocal.TunnelSend in mormot.net.tunnel detects a session-only closure frame while fHandshake still exists. It records fClosePortNotified, signals fHandshakeEvent, marks fClosed and exits instead of pushing the empty frame into the handshake queue.
Fixes
mormot.net.tunnel
9609945c+12-2
net: fixed TTunnelLocal early shutdown
Impact
WaitForHandshake can return promptly when the remote endpoint closes before setup completes. Deferred tunnels no longer mistake a close notification for handshake data or wait until the timeout.
Upgrade recommended
Take this fix with the complete WaitForHandshake/OpenSocket series in build 2.4.16776 and test peer closure during setup.
Units
7
Medium
WebSocket frame logging no longer resets remote-log state unnecessarily
TWebSocketProcess.Log in mormot.net.ws.core now calls TSynLog.DisableRemoteLog only when its DisableRemoteLog argument is true, both before and after writing the frame. SendFrame makes that true argument explicit in the call site.
Fixes
mormot.net.ws.core
72c81483+7-5
net: fixed TWebSocketProcess.Log() code
Impact
Receive-side or other log calls made with DisableRemoteLog=false no longer force the logger back to remote-enabled state. SendFrame still suppresses remote forwarding around its own trace to avoid recursive WebSocket logging.
Worth a look
If WebSocketLog forwards to a remote sink, verify that receive and send traces now preserve the intended remote-log suppression state.
Units
8
Medium
ECDHE setup failure now raises a specific tunnel exception
TTunnelLocal.OpenInternal in mormot.net.tunnel replaces a silent exit after Ecc256r1SharedSecret failure with ETunnel.RaiseUtf8. The exception identifies TTunnelLocal and includes the local port.
Fixes
mormot.net.tunnel
8d1d4fc7+4-3
net: another Tunnel logic improvement
Impact
An invalid peer ECDHE public key now produces an explicit failure rather than an ambiguous zero-like Open result. Callers that deliberately feed malformed handshakes should expect ETunnel on this path.
Worth a look
Review exception handling around TTunnelLocal.Open and OpenSocket if untrusted peers can supply handshake keys.
Public API
TTunnelLocal.Openbehaviour-changed — Ecc256r1SharedSecret failure now raises ETunnel instead of exiting silently.
Units
9
Medium
Applications can hand an existing connected socket to TTunnelLocal
mormot.net.tunnel exposes TTunnelLocal.WaitForHandshake and adds TTunnelLocal.OpenSocket. OpenSocket validates a non-nil socket and port, transfers ownership by clearing the caller variable, and shares handshake setup with Open through the protected OpenInternal method. The ITunnelOpen documentation now describes an SSH -R-like demand-driven sequence.
New features
mormot.net.tunnel
c38c36da+158-44
net: introduced late access to the local Tunnel socket
Impact
VNC-style or other reverse forwarding can defer the backend connection until a real local client arrives. Existing Open callers keep their source contract; new OpenSocket callers must not close or reuse Socket after a valid call because ownership has moved to TTunnelLocal.
Worth a look
For demand-driven forwarding, test socket ownership, both handshake directions, timeout and peer-close paths before replacing an existing Open-based flow.
Public API
TTunnelLocal.WaitForHandshakeadded — Waits for the first queued peer handshake without consuming it.TTunnelLocal.OpenSocketadded — Starts tunnelling over an already-connected TNetSocket and takes its ownership.
Units
10
Medium
One helper now produces every unpredictable nine-digit session number
mormot.crypt.core adds the public Random9Digits function. It takes three candidate cardinals from Random128, clears the temporary 128-bit buffer and returns 100000000..999999999, or zero only if every candidate is zero. TTunnelRelay.PrepareNewSession in mormot.net.tunnel now calls this helper.
New features
mormot.crypt.core+1
da7e1c2f+23-11
crypt: new Random9Digits() function
Impact
Tunnel session identifiers retain their 32-bit wire representation but now always have exactly nine decimal digits and use the framework CSPRNG. Other Delphi/FPC code may reuse the helper when that range and zero-as-failure contract are suitable.
Upgrade recommended
Tunnel relay users should land on build 2.4.16776 so the unpredictable allocation and its final range helper are taken together.
Public API
Random9Digitsadded — Returns an unpredictable cardinal in 100000000..999999999, or zero if Random128 is unusable.
11
Medium
Delphi 10–10.3 receives targeted pointer and inlining workarounds
mormot.defines.inc defines ISDELPHI10_103 for compiler versions 30 through 33. mormot.core.buffers disables inline on FromVarInt32 for that range, and mormot.core.base rewrites typed pointer casts in AppendShortCurr64 from @p[index] to pointer arithmetic that those compilers accept.
Compiler & platform
mormot.core.base+1
92d840ee+10-6
core: circumvent Delphi 10.x compiler bugs
Impact
Projects compiled with Delphi 10, 10.1, 10.2 or 10.3 avoid known compiler failures in variable-integer decoding and currency text formatting. Generated behavior is intended to stay the same; FPC and other Delphi versions do not use the new conditional.
Upgrade recommended
Delphi 10–10.3 teams should rebuild the affected targets with build 2.4.16776 and rerun serialization plus Currency-formatting tests.
12
Low
TNetAddr recognizes the full IPv4 loopback block and IPv6 ::1
mormot.net.sock adds the public TNetAddr.IsLoopback method. It returns true for any AF_INET address whose first byte is 127 and for the AF_INET6 ::1 byte pattern, and false for other or undefined address families.
New features
mormot.net.sock
be380064+20-2
net: new TNetAddr.IsLoopback method
Impact
Network code can perform one family-aware local-address check instead of comparing only 127.0.0.1. Existing callers are unaffected; the tunnel accept path adopts the helper in a later commit.
Public API
TNetAddr.IsLoopbackadded — Returns true for 127.x.x.x and ::1 addresses.
Units
13
Low
CheckHash accepts raw buffers as well as managed strings
mormot.core.test adds a TSynTestCase.CheckHash overload taking data: pointer and len: PtrInt. The existing RawByteString overload delegates to it, and the shared implementation computes Hash32(data, len) before producing the diagnostic assertion.
New features
mormot.core.test
3ad5bbe2+13-4
core: new TSynTestCase.CheckHash() overload
Impact
Tests can validate streams, short strings and arbitrary memory without first allocating a RawByteString. Production runtime behavior is unaffected because the addition is in the testing unit.
Public API
TSynTestCase.CheckHash(pointer, PtrInt, cardinal, RawUtf8)added — New overload hashes an explicit memory buffer and length.
Units
14
Low
Relay scans and cached-info copies use tighter pointer loops
mormot.net.tunnel introduces PTunnelRelayConsole and rewrites HasConsolePrepared and ConsolesInfo to advance record pointers. TTunnelList.GetAllInfo also removes structured try/finally blocks around short lock-protected assignments while keeping the same lock and exit behavior.
Performance
mormot.net.tunnel
89996223+28-28
net: slightly optimized TTunnelRelay process
Impact
Relay metadata enumeration performs less index and exception-frame work. Public results and locking semantics are intended to remain unchanged, so no Delphi/FPC application update is required.
Units
15
Low
FPC POSIX thread destruction avoids the RTL’s fixed wait when possible
TThreadAbstract overrides Destroy only under FPCPOSIX. When the main thread frees an active non-suspended thread, it calls Terminate and briefly loops over CheckSynchronize and SleepHiRes until Finished or 100 ms, before invoking the inherited destructor.
Performance
mormot.core.threads
efc0950e+28-2
core: override TThreadAbstract.Destroy on FPC POSIX
Impact
Short-lived FPC POSIX thread objects can finish before the inherited RTL path imposes its usual 100 ms WaitFor delay. Delphi and Windows code is not compiled through this override.
Public API
TThreadAbstract.Destroybehaviour-changed — On FPC POSIX, active threads receive a bounded cooperative finish loop before inherited destruction.
Units
16
Low
The internal INI section matcher uses a Delphi-10-friendly loop
IdemPChar2 in mormot.core.fmt is rewritten from a repeat loop with a temporary AnsiChar into a while loop that compares table[up[PtrUInt(p)]] directly and advances up only on a match.
Compiler & platform
mormot.core.fmt
00f6828c+12-13
core: refactored INI parsing for Delphi 10.x
Impact
INI section-name matching keeps the same case-normalized behavior while avoiding a code shape that caused problems in Delphi 10.x. FPC and newer Delphi application APIs are unchanged.
Units
17
Low
Windows canary builds receive current desktop and server release labels
mormot.core.os updates its build lookup tables: desktop build 29570 maps to Windows 11 27H2, desktop 26300 remains 26H2, and server build 29651 maps to Windows Server 26H2. The Delphi test batch also enables optimization and NO_UI for configured non-default compilers.
Compiler & platform
mormot.core.os
61a6fc1b+12-9
core: detect Windows 11 27H2 and Windows Server 26H2 canary versions
Impact
OSVersionText can report the intended labels on those preview builds instead of falling back to an older bucket. Runtime feature selection is unchanged because this diff only adjusts descriptive lookup tables.
Units
18
Low
Command-line FPC Windows tests explicitly opt out of UI units
test/build_fpc.sh adds -dNO_UI for win* targets, and test/build_winarm.bat adds the same define for aarch64-win64. This prevents mormot2tests from requiring Lazarus Interfaces and test.ui.pdf when no widgetset path is configured.
Compiler & platform
55d28b7f+4-2
tests: define NO_UI in the command line FPC build scripts
Impact
The repository command-line test build works again on FPC Windows and aarch64-win64 without LCL. Lazarus package builds retain UI coverage, and application build flags are not changed.
19
Low
Deferred tunnels gain direct and WebSocket end-to-end coverage
test.net.proto adds TunnelDeferred. The test prepares both relay endpoints, accepts a viewer socket before connecting the backend, waits for the handshake, exchanges VNC-style banners in both directions and repeats the flow through SOA callbacks over WebSockets.
Tests
e22ca7df+186-2
tests: cover deferred Tunnel connection
Impact
There is no application-code change. The new demand-driven TTunnelLocal path is now exercised both without transport serialization and through the real WebSocket callback route.
20
Low
The Lazarus test project recognizes ten expected exception classes
test/mormot2tests.lpi registers ten exception class names, including EHttpSocket, EYamlException, EStreamError and EJsonObjectDecoder, in its Lazarus debugger configuration.
Tests
1b9767fa+34-2
test: ease mormot2tests debugging by registering some exceptions
Impact
This only changes debugger handling in the Lazarus test project. Framework code, test behavior outside debugging and application builds are unchanged.
21
Low
Regression hashes now report expected and actual values consistently
Four test units replace direct Hash32 comparisons with TSynTestCase.CheckHash. Pointer-and-length buffers, serialized variants, SOA JSON and generated PDF memory now use the same diagnostic assertion, with PDF constants rewritten in hexadecimal.
Tests
07032883+14-14
tests: use new CheckHash()
Impact
Failed regression tests provide clearer hash diagnostics, especially where PDF font embedding differs by system. Framework runtime and application code are unchanged.
22
Low
Loopback checks now use shared address helpers and constants
mormot.net.sock replaces two uses of cLocalhost text with IP4local. TTunnelLocalThread.DoExecute in mormot.net.tunnel uses TNetAddr.IsLoopback instead of comparing only fClientAddr.IP4 with cLocalhost32.
Housekeeping
mormot.net.sock+1
0ce4b076+5-5
net: minor loopback definitions usage
Impact
Local tunnel admission now follows the shared IPv4 and IPv6 loopback definition, so ::1 is accepted as local. Existing IPv4 localhost behavior remains unchanged.