Deprecate "ip" in favour of "host" for domain fronting
Per review on #480: warn-and-ignore for the IP-shaped paths,
mirroring the net.Dialer.DualStack precedent — a config that
sets only "ip" will warn at startup and effectively disable
domain-fronting until the user switches to "host".
- mtglib.ProxyOpts: add DomainFrontingHost; mark DomainFrontingIP
Deprecated and warn-and-drop in NewProxy.
- internal/config: GetDomainFrontingHost returns only
[domain-fronting].host; deprecated keys are no longer used to
derive the dial target. runProxy logs a startup warning per
deprecated key that is set.
- internal/cli: add --domain-fronting-host; --domain-fronting-ip
flag is parsed only so the runtime warning can fire.
- internal/cli/doctor: redirect the existing 2.3.0 entry at "host"
and add a 2.4.0 entry for [domain-fronting].ip.
- example.config.toml: mark # ip = ... as deprecated.
doctor: use WaitGroup.Go and recover panics in DC probes
Address review feedback on #485:
- switch to sync.WaitGroup.Go (Go 1.25+) for the per-DC goroutine
- recover panics inside the goroutine and record them as that DC's
error, so a single panicking probe no longer crashes the whole
doctor run and the remaining DCs still report their results
Each DC dial uses a 10s timeout, and "checkNetwork" iterates 6 DCs
sequentially, so worst case is ~60s when egress is broken. Probing in
parallel collapses the worst case to a single timeout window while
preserving the existing DC-ordered output.
Refs #482
Follow-up to the previous commit on this branch:
- Rename Config.GetDomainFrontingIP -> GetDomainFrontingHost. The
helper now returns a hostname or an IP, so the old name was a lie.
Drop the unused defaultValue net.IP parameter (every caller passed
nil). Update internal/cli/run_proxy.go and internal/cli/doctor.go;
rename the misleading `ip` local var in doctor.go to `override`.
- Add TOML fixtures (domain_fronting_host.toml, domain_fronting_ip.toml)
so the new field is exercised through the actual Parse()->JSON->Config
path users hit, not just via direct .Set() calls. Plus a positive
backward-compat test confirming an `ip`-only legacy config still
validates and resolves correctly, and a no-fronting test confirming
the unset case returns empty.
- Clarify example.config.toml: `ip` is kept for backward compatibility,
not because it has stricter validation semantics worth choosing over
`host`.
mtglib.ProxyOpts.DomainFrontingIP keeps its name (public API).
Add public-ipv4/public-ipv6 config options for manual IP override
On some servers ifconfig.co is unreachable (e.g. Hetzner, AdGuard DNS
blocklists), causing 'mtg doctor' SNI-DNS check and 'mtg access' link
generation to fail. New config options allow specifying public IPs
manually, with automatic detection as fallback.
Fixes #405