mailru: large default batch (BatchSizeHinter); node-install.sh → node-v1.4.2

The R7 server cuts an anonymous editor connection with 4004 after ~12 chat
messages regardless of their size, so the 8 KB default batch spent almost the
whole per-connection budget on tiny messages — tens of KB/s. Add
transport.BatchSizeHinter so a carrier capped by message count (not bytes) can
raise the coalescing default; newLink passes the hint to NewBatchedTransport
(OPENFLUX_BATCH_BYTES still overrides). mailru hints 500 KB → ~800 KB/s/burst
e2e. Every other transport is byte-identical (type assertion fails → hint 0).

node-install.sh pins node-v1.4.2 with the 0.7.3 exit-node hashes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
p1neappleXpress
2026-10-14 12:10:00 +03:00
co-authored by Claude Opus 4.8
parent a2dec38c3c
commit fd5b7c3ad7
6 changed files with 53 additions and 7 deletions
+10
View File
@@ -5,6 +5,16 @@ All notable changes to the OpenFlux core. Format loosely follows
## [Unreleased]
## [0.7.3] - 2026-10-14
### Changed
- **Mail.ru is much faster.** The Mail.ru docs server cuts an anonymous editor after about a dozen
chat messages no matter how big they are, so the tunnel now coalesces far more into each message
before that cut — end-to-end throughput rises from tens of KB/s to roughly 800 KB/s per burst.
Only the Mail.ru carrier changes its default batch size; every other transport is byte-for-byte
unchanged, and `OPENFLUX_BATCH_BYTES` still overrides it.
## [0.7.2] - 2026-10-13
### Fixed
+4 -4
View File
@@ -50,10 +50,10 @@
set -u
umask 077
CORE_VERSION="node-v1.4.1"
SHA_amd64="f053ca98397a8d9f30305c01dafae50b7b06602bd3260f7341a70bc7d4ba2aad"
SHA_arm64="18c69b00a8b4072e9573d127eeaae88d915e551781eb733d0fece99c6d4f47bd"
SHA_arm="9f7ee1ec2009c9d86141dfd8e1e07c92faed2502b8dc6fc63f237447f943fb32"
CORE_VERSION="node-v1.4.2"
SHA_amd64="801f9890c439b8f82030d93fee52d03c0984145eaec4498f0d51b62be007bf4e"
SHA_arm64="c63705cb85be8a0ac772de04545177f6cf87a76672fda14a5906368ed4141ac4"
SHA_arm="c9d53248655e0a0bd70e7c95376fdfc1d035d0efe3c5a237a93ec51baa498142"
# The repository this script and its core come from: the core is one of its
# node-v* releases, and the updater follows them (UPDATE_CONF may override
# that with a "repo=owner/name" line).
+10 -2
View File
@@ -59,12 +59,20 @@ func envInt(name string, def int) int {
return def
}
func NewBatchedTransport(inner Transport) *BatchedTransport {
// NewBatchedTransport wraps inner with the coalescing layer. An optional
// batchBytesHint (the first variadic value, when > 0) raises the default batch
// size for a carrier whose per-connection limit is on message COUNT, not bytes
// — see BatchSizeHinter. OPENFLUX_BATCH_BYTES still overrides it.
func NewBatchedTransport(inner Transport, batchBytesHint ...int) *BatchedTransport {
defBatchBytes := defaultMaxBatchBytes
if len(batchBytesHint) > 0 && batchBytesHint[0] > 0 {
defBatchBytes = batchBytesHint[0]
}
b := &BatchedTransport{
Transport: inner,
queue: make(chan []byte, batchQueueDepth),
lingerMs: envInt("OPENFLUX_BATCH_LINGER_MS", defaultLingerMs),
maxBatchBytes: min(envInt("OPENFLUX_BATCH_BYTES", defaultMaxBatchBytes), maxFrameBytes-65537),
maxBatchBytes: min(envInt("OPENFLUX_BATCH_BYTES", defBatchBytes), maxFrameBytes-65537),
maxBatchCount: min(envInt("OPENFLUX_BATCH_COUNT", defaultMaxBatchCount), maxFrameRecords-1),
stopCh: make(chan struct{}),
}
+13
View File
@@ -246,6 +246,19 @@ func (t *MailruDocsTransport) Start() error {
return nil
}
// mailruPreferredBatchBytes is the default coalescing batch size for the chat
// carrier. The R7 server cuts an anonymous editor connection with 4004 after
// ~12 chat messages regardless of their size, so a large batch fits far more
// tunnel data into that fixed message budget before the reconnect. Measured
// end-to-end (d14 exit <-> 212 client, cachefly 10 MB via socks5h): the 8 KB
// default gave the old tens-of-KB/s; ~500 KB reaches ~860 KB/s per burst, while
// 1 MB is slower and far more variable (a bigger loss unit per 4004 cut).
// OPENFLUX_BATCH_BYTES overrides this (see transport.BatchSizeHinter).
const mailruPreferredBatchBytes = 500_000
// PreferredBatchBytes implements transport.BatchSizeHinter.
func (t *MailruDocsTransport) PreferredBatchBytes() int { return mailruPreferredBatchBytes }
func (t *MailruDocsTransport) Send(data []byte) error {
if !t.IsConnected() {
return fmt.Errorf("transport not connected")
+5 -1
View File
@@ -189,12 +189,16 @@ func (s *Session) newLink(name string, raw Transport, secret, context string, pr
classic, codec := s.classic, s.classicCodec
s.mu.Unlock()
enc.SetAlternateContexts(alternates)
batchHint := 0
if h, ok := raw.(BatchSizeHinter); ok {
batchHint = h.PreferredBatchBytes()
}
link := &transportLink{
name: name,
raw: raw,
demux: d,
encrypted: enc,
batched: NewBatchedTransport(enc),
batched: NewBatchedTransport(enc, batchHint),
priority: priority,
}
if classic != ClassicOff {
+11
View File
@@ -33,6 +33,17 @@ type TransportStats struct {
Uptime time.Duration
}
// BatchSizeHinter is an optional interface a transport implements to raise the
// default coalescing batch size for its carrier. A carrier capped by the number
// of messages per connection rather than by bytes wants each message as large
// as possible: the Mail.ru docs chat channel, for instance, is cut by the
// server's anti-abuse after ~12 messages regardless of their size, so a small
// batch wastes most of the per-connection budget. newLink passes the hint to
// NewBatchedTransport; OPENFLUX_BATCH_BYTES still overrides it.
type BatchSizeHinter interface {
PreferredBatchBytes() int
}
func DefaultConfig() TransportConfig {
return TransportConfig{
MaxReconnectAttempts: 999999,