Add PROFILE config key with mobile / censored / throughput / stable presets#169
Open
Isusami wants to merge 4 commits into
Open
Add PROFILE config key with mobile / censored / throughput / stable presets#169Isusami wants to merge 4 commits into
Isusami wants to merge 4 commits into
Conversation
Introduces the PROFILE knob with the precondition the architect flagged: the loader now builds a "defined" map of TOML keys explicitly set by the operator (mirroring the existing JSON loader path) and applyProfile only overrides knobs the operator did not set. The stable preset is an empty override bag, intentionally identical to omitting PROFILE. Tests cover stable=omitted equivalence, unknown-profile error, the precedence guarantee (explicit PACKET_DUPLICATION_COUNT wins over the preset), a snapshot infrastructure for later presets, and a reflection guard that catches profileOverrides field-name typos at test time.
Optimizes the cadence ladder for high-latency, battery-constrained links: doubles the cooldown/cold ping intervals and the matching warm/cool/cold thresholds so radios get more sleep, drops PacketDuplicationCount to the clamp floor (1) for bandwidth, lifts the data NACK initial delay to 0.6s so a single jittery RTT does not flood resend requests, and halves the local DNS cache to keep memory pressure down. Coherence note: a future B-series PR will need to extend this preset to also set MIN_DUP/MAX_DUP coherently once adaptive duplication lands; the preset comment documents that boundary explicitly.
Tuned for hostile/lossy paths where survivability is paramount: high duplication (4, well within the 1..10 clamp), more aggressive ping cadence so a failing resolver is detected sooner, a wider MTU search window in both directions so the prober can find any path that works, more retry-friendly ARQ parameters (initial RTO 2s, max data retries 2400), and BASE_ENCODE_DATA on by default for resolvers that prefer label-safe payloads.
Optimized for raw bandwidth on healthy paths. Drops PacketDuplicationCount to 1, picks the BalancingLowestLatency selector (strategy 4), turns on ZSTD compression in both directions, and narrows the MTU search range so the prober converges on a stable working size instead of widening probes. This preset deliberately trades duplication-for-survivability for raw bandwidth. Operators must opt in explicitly via PROFILE = "throughput" — never a silent default; it is not appropriate as a global default for the project.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a single
PROFILEconfig key that picks a coherent group of defaults so non-technical users do not have to tune ~50 individual knobs. Four presets ship:stable— current defaults (no-op; explicit baseline).mobile— slower ping cadence (2× cooldown / cold intervals + proportional thresholds),PACKET_DUPLICATION_COUNT=1, raised NACK initial delay, halved local DNS cache.censored— survivability-first:PACKET_DUPLICATION_COUNT=4, wider MTU range (28–200 up / 60–900 down), retry-friendly ARQ (ARQInitialRTOSeconds=2.0,ARQMaxDataRetries=2400),BASE_ENCODE_DATA=true.throughput— bandwidth-first:PACKET_DUPLICATION_COUNT=1,RESOLVER_BALANCING_STRATEGY=4(lowest latency), ZSTD compression on both directions, narrow MTU range (120–150 up / 400–500 down).Explicit keys in
client_config.tomlalways win over the preset.PROFILEunset or set tocustom/stableis a no-op — existing configs are unaffected.Example usage
Step 1 — Pick the profile that matches your situation:
stable(or leave it out)mobilecensoredthroughputStep 2 — Add one line to
client_config.toml:That's it. The client now uses sensible settings for that situation. No other config changes needed.
Optional — Override a single knob:
Anything you write explicitly in your config always wins over the preset. So you can pick a preset for everything you don't care about and tweak just the one or two knobs you do.
How it works
Preset overrides are applied after TOML decode and before
finalizeClientConfig. The loader now usestoml.MetaDatato know which keys were explicitly defined in the user's TOML, and the preset only writes a field if that field was not explicitly set. This makes precedence deterministic and safe.Why
The current
client_config.toml.simplelists ~50 knobs that interact in non-obvious ways (ping cadence, duplication, ARQ RTO, MTU range, compression). Most users never tune them. Presets give a one-word choice that picks consistent defaults for the four most common use cases.Changes
PROFILEplumbing,stablepreset (no-op),toml.MetaData-driven explicit-key precedence, and the snapshot-test infrastructure (testdata/profile_*.golden.json).mobilepreset.censoredpreset.throughputpreset (operator-choice preset; explicitly trades duplication-for-survivability for raw bandwidth).Backward compatibility
PROFILEomitted → identical to today's behavior.PROFILE=stable→ byte-for-byte identical to today (snapshot-asserted).Tests
internal/config/testdata/profile_*.golden.json(regenerate withMASTERDNSVPN_UPDATE_PROFILE_GOLDEN=1 go test ./internal/config/ -run TestProfile.*Snapshot).profileOverridesfield-name typos at test time so a misnamed knob in a future preset fails loudly instead of silently no-op'ing.PROFILEvalue returns a config-load error.go build ./...,go test ./...,go vet ./...all pass.Risk
Low. The feature is opt-in (no
PROFILE= no behavior change), all changes are ininternal/config/, no wire-protocol surface is touched, and the snapshot tests guard against silent drift.Open questions for maintainer review
A few preset values were judgment calls; happy to adjust:
mobilecadence multiplier — literal 2× onPingCooldownIntervalSecondsandPingColdIntervalSeconds. Acceptable?mobileNACK delay — bumped from0.1s→0.6s(6×). If a smaller bump is preferred (e.g.0.3s), trivial to change.censoredduplication — picked4(max-survivability inside the1..10clamp). Could be3.censoredMTU envelope — picked28..200upload and60..900download. Wider than defaults; still insidefinalizeClientConfig's validation.throughputMTU envelope —120..150upload,400..500download. Tight but leaves the prober a workable window.Each of these is one line in
internal/config/profiles.go; happy to revise based on operator experience.Future work (out of this PR)
mobileandthroughputwill get cleaner adaptive-duplication wiring onceMIN_DUP/MAX_DUPland in a follow-up PR. Until then, the presets setPACKET_DUPLICATION_COUNTdirectly; the source comments mark the migration point.-doctorsubcommand to validate a chosen profile's resolved config is planned as a separate PR.