Auto-update anyone_hosts from the .anyone DNS service (v2)#147
Open
jim-toth wants to merge 1 commit into
Open
Conversation
Reworked from PR #145 per its production-readiness review. The client fetches a fresh anyone_hosts mapping when new directory information arrives and on a periodic (jittered) schedule. Fetches are routed by .anyone name over hidden-service circuits: linked directory streams for this purpose now go through the same rewrite/attach path as SOCKS client streams (connection_ap_make_link_onion), which is where .anyone names are resolved -- the v1 approach attached them as general exit streams and could never complete. Fetched files are installed only if they are non-empty, within DNSMappingFileMaxSize, carry a valid signature from a trusted DNS signer (not configurable), are unexpired per valid-until, contain at least one mapping, and are not older (by published time) than the installed mapping. Byte-identical refetches skip the rewrite. Configuration is deliberately minimal: AnyoneHostsUpdate, AnyoneHostsUpdateInterval (floored at 1 hour, jittered +/-10%), and AnyoneHostsURL. Target selection tries configured URLs then built-in defaults, advancing only past failing servers.
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
Automatic updating of the
anyone_hostsDNS mapping file, reworked from #145 per its production-readiness review. The client fetches a fresh mapping from the.anyoneDNS service nodes when new directory information arrives and on a periodic (jittered) schedule. Fetches are onion-routed to the DNS service's hidden service by.anyonename.What changed vs. #145
Transport actually works now. v1 handed the
.anyonename toconnection_ap_make_link(), which attaches linked streams directly as general exit streams — the name was never resolved, so every fetch failed at the exit with RESOLVEFAILED. v2 addsconnection_ap_make_link_onion()(connection_edge.c), which routes the linked stream throughconnection_ap_handshake_rewrite_and_attach()— the same path SOCKS client streams take — so the.anyonename is resolved via the mapping and attached to a hidden-service circuit, withentry_cfg.onion_trafficenabled for the internal fetch.Response validation. A fetched file is installed only if it:
DNSMappingFileMaxSize,verify/anymodes are gone),valid-until(now actually enforced; previously parsed and discarded),publishedtime than the installed mapping (anti-rollback for replayed signed files).Byte-identical refetches are accepted without rewriting the file. Validation/installation policy lives in the anyone module (
anyone_hosts_handle_fetch_response); dirclient keeps only a thin dispatch.Scope trimmed to 3 options (v1 had 6):
AnyoneHostsUpdate(0|1, default 1)AnyoneHostsUpdateInterval(default 12 hours, floor 1 hour, ±10% jitter so fleets don't fetch in lockstep)AnyoneHostsURL(repeatable override, tried before built-in defaults)Dropped:
AnyoneHostsUpdateTrigger(both triggers hardcoded — uniform client behavior over knobs),AnyoneHostsFetchPath(hardcoded/tld/anyone, deletes the header-smuggling validation),AnyoneHostsSignatureRequirement(strict always).Review findings addressed:
DEFAULT_ANON_DNS_MAPPINGonly, so fetched content can't steer future fetch targets._free_all()removed;.anyonesuffix checks usestrcmpend();approx_time()used consistently.directory_initiate_request()returns void and can fail before any connection exists.Parser:
anyone_hosts_parse_and_verify_ex()now exposespublished/valid-until(mockable for tests); the old signature remains as a wrapper.Testing
directory_initiate_request), address extraction, and response validation incl. anti-rollback and size cap (mocked signature verifier driven by body markers).Manual testing needed before merge (the untestable-in-unit part)
The routing path is exactly what unit tests cannot cover — this is where v1 silently failed:
AnyoneHostsUpdate 1on a live/stage network, verify a fetch launches and completes:anyone_hostsmtime/content updates from the live DNS node (DNS 1).Anyone dns address mapping foundfor the DNS node name, followed by descriptor fetch / rend circuit activity, noRESOLVEFAILEDat an exit).AnyoneHostsURLat a dead placeholder (DNS 2/3), confirm the next attempt (after the 1h retry gap) moves to the next target and eventually succeeds via DNS 1.AnyoneHostsUpdate 0: no fetches scheduled or launched.AnyoneHostsURLentries are rejected with clear errors.