WIP: dns auto-update feature#145
Open
jim-toth wants to merge 11 commits into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces an automatic update mechanism for the anyone_hosts DNS mapping file, integrating it into the directory-client response handling and the mainloop periodic/consensus-triggered flow.
Changes:
- Add a new directory connection purpose for fetching
anyone_hostsand route it through the dirclient response-handling path. - Introduce a new
feature/anyonemodule to schedule/triggeranyone_hostsfetch attempts (periodic + consensus-triggered). - Add new configuration options and manpage/docs to control auto-update behavior and signature acceptance policy.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/include.am | Wires the new feature/anyone build include into the overall build. |
| src/feature/dircommon/directory.h | Adds a new DIR_PURPOSE_FETCH_ANYONE_HOSTS purpose constant. |
| src/feature/dircommon/directory.c | Treats the new purpose as requiring anonymity. |
| src/feature/dirclient/dirclient.c | Adds request/response handling for fetching, verifying, and atomically writing the anyone_hosts file; triggers update kick after consensus. |
| src/feature/anyone/include.am | Adds build rules for the new anyone-hosts update module. |
| src/feature/anyone/anyone_hosts_update.h | Declares the anyone-hosts update subsystem API. |
| src/feature/anyone/anyone_hosts_update.c | Implements URL list building and the periodic/consensus-triggered fetch initiation logic. |
| src/core/mainloop/mainloop.c | Registers a new periodic event and initializes the anyone-hosts update subsystem. |
| src/app/config/or_options_st.h | Adds new config fields controlling anyone-hosts auto-update and signature policy. |
| src/app/config/config.c | Adds default values and validation for the new configuration options. |
| doc/man/anon.1.txt | Documents new options and expands documented units for DNSMappingFileMaxSize. |
| changes/anyone-hosts-autoupdate | Adds a changelog entry for the new feature and documentation updates. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+214
to
+219
| fetch_in_progress = 1; | ||
| last_attempt_time = now; | ||
|
|
||
| directory_initiate_request(req); | ||
| directory_request_free(req); | ||
|
|
| /* Atomically write the file using a temp file + rename. */ | ||
| char *hosts_fname = get_datadir_fname("anyone_hosts"); | ||
| char *hosts_fname_tmp = get_datadir_fname("anyone_hosts.tmp"); | ||
| int write_ok = (write_str_to_file(hosts_fname_tmp, body, 0) == 0); |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Jim Toth <jim@memeticblock.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Jim Toth <jim@memeticblock.com>
Comment on lines
+180
to
+185
| /** | ||
| * Launch one fetch if conditions are met. Called both from the consensus | ||
| * hook (anyone_hosts_update_maybe_kick) and from the periodic callback. | ||
| */ | ||
| static void | ||
| maybe_launch_fetch(time_t now) |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Signed-off-by: Jim Toth <jim@memeticblock.com>
Comment on lines
+4098
to
+4103
| if (!options->AnyoneHostsFetchPath || | ||
| !strlen(options->AnyoneHostsFetchPath) || | ||
| options->AnyoneHostsFetchPath[0] != '/') { | ||
| REJECT("AnyoneHostsFetchPath must be a non-empty absolute path " | ||
| "beginning with '/'."); | ||
| } |
Comment on lines
+100
to
+113
| SMARTLIST_FOREACH_BEGIN(_lines, const char *, _line) { \ | ||
| const char *_sp = strchr(_line, ' '); \ | ||
| if (_sp && *(_sp + 1) && \ | ||
| strcmpstart(_line, "anyone-hosts-") != 0) { \ | ||
| const char *_addr = _sp + 1; \ | ||
| size_t _alen = strlen(_addr); \ | ||
| if (_alen >= 7 && !strcmp(_addr + _alen - 7, ".anyone")) \ | ||
| smartlist_add(urls, tor_strdup(_addr)); \ | ||
| } \ | ||
| } SMARTLIST_FOREACH_END(_line); \ | ||
| SMARTLIST_FOREACH(_lines, char *, _s, tor_free(_s)); \ | ||
| smartlist_free(_lines); \ | ||
| tor_free(_copy); \ | ||
| } while (0) |
| int idx = current_url_index % smartlist_len(urls); | ||
| const char *onion_addr = smartlist_get(urls, idx); | ||
|
|
||
| log_info(LD_DIR, "Launching anyone_hosts fetch from %s", onion_addr); |
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 automatic updating of the
anyone_hostsDNS mapping file. The client now fetches a fresh copy of the mapping from the.anyoneDNS service nodes — triggered when new directory information arrives and/or on a periodic schedule — so operators no longer need to ship/update the file manually.What's included
New feature: anyone_hosts auto-update
src/feature/anyone/anyone_hosts_update.c..anyoneonion service (plain HTTP on port 80), with an ordered URL fallback list (config → previously saved mapping addresses → built-in default).DNSMappingFileMaxSize), a configurable signature policy, and writes the file atomically.DIR_PURPOSE_FETCH_ANYONE_HOSTSwired throughdirclient/dircommon.New configuration options
AnyoneHostsUpdate,AnyoneHostsURL,AnyoneHostsUpdateInterval,AnyoneHostsFetchPath,AnyoneHostsUpdateTrigger,AnyoneHostsSignatureRequirement.Directory client: name-based onion routing
anon_onion_addressfield +directory_request_set_anon_onion_address()setter so a directory request can be routed to an onion service by name rather than by IP.directory_initiate_request()uses this address for the connection and skips the numeric-address requirement for these fetches.Documentation
DNSMappingFileMaxSizenow documents bit-based units (KBits/MBits/GBits/TBits), consistent with other MEMUNIT options.DNSMappingFileMaxSizeonly limits loading an existing file; a missing file is always recreated with the default mapping.Code review fixes (this revision)
anyone_hosts_update_callbackto resolve a symbol collision with the mainloop wrapper.X-Anyone-Onionheader approach with proper name-based onion routing so fetches actually launch..anyone.confline.hinclude (build fix).Testing
Manual testing checklist
Setup
AnyoneHostsUpdate 1.anyone_hostsfile exists (or is recreated with the default mapping when missing).Log info(ornotice) to observe fetch/scheduling log lines.Periodic trigger
AnyoneHostsUpdateTrigger periodicand a shortAnyoneHostsUpdateInterval, verify a fetch is launched after the interval elapses.anyone_hostsfile is updated on disk (mtime/contents change) after a successful fetch.Consensus trigger
AnyoneHostsUpdateTrigger consensus, verify a fetch is kicked when fresh directory info / a new consensus arrives.AnyoneHostsUpdateTrigger both, verify both paths can trigger a fetch.URL fallback ordering
AnyoneHostsURLset, verify it is tried first.AnyoneHostsURLat an unreachable/invalid.anyoneaddress; verify it falls back to addresses from the saved mapping, then the built-in default.Routing
.anyonename (no spurious "without a remote DirPort" warnings for these fetches).Size cap & signature policy
DNSMappingFileMaxSize; verify it is rejected and the existing file is left intact.AnyoneHostsSignatureRequirement strict: verify an unsigned/invalid-signature file is rejected.AnyoneHostsSignatureRequirement verify: verify a valid signature is accepted and an invalid one rejected.AnyoneHostsSignatureRequirement any: verify the file is accepted regardless of signature.Disable / config validation
AnyoneHostsUpdate 0, verify no fetches are scheduled or launched.AnyoneHostsUpdateTrigger/AnyoneHostsSignatureRequirement; verify config validation rejects them with a clear error.Documentation
DNSMappingFileMaxSizewording.