This PR has an intention of resolving URLs by using multiple endpoints
that identify an IP address of the service. This is handy if one service
is blocked for some reason.
The detection mechanism follows this logic:
1. It tries to access all services in parallel
2. If service respond with some error (like, no route to host for IPv6),
then we accurately collect those errors and return a merged one
3. In case of the first IP resolved, we immediately return it.
Also, this PR refactors how access and SNI check are performed.
`doctor`'s checkSecretHost and the proxy-startup warnSNIMismatch each
carried their own copy of the same logic: resolve the secret hostname,
determine the server's public IPv4/IPv6 (config first, getIP fallback),
and compare the two sets.
Extract that data-gathering into runSNICheck (internal/cli/sni_check.go),
returning an sniCheckResult. The success decision stays with each caller
because the rules genuinely differ — `doctor` reports OK when any family
matches, while the startup warning requires every detected family to
match — so only the gathering is shared, not the verdict.
No behavior change: both callers produce byte-identical output and the
same return values as before.