Repository navigation
chore: bump to 0.3.10-alpha.10 for the dns check method - #46
Merged
Merged
Conversation
A dns check (design 32 S5a) asks one resolver one question and judges the answer. The target's scheme picks the transport: https posts application/dns-message (RFC 8484, ID 0), tls frames the message behind a two-byte length inside TLS (RFC 7858), and udp and tcp are plain DNS. The resolver's host is resolved once and every address judged by the rule http and tcp checks follow, so a resolver that resolves to a private address is refused with destination_refused before anything is sent. One query per run, with recursion desired and an EDNS(0) record advertising 1232 bytes; a truncated UDP answer is asked again once over TCP. The check's timeout bounds the whole exchange, a DoH body over 64 KiB is refused unread, DoH and DoT verify the certificate against the host and record cert_not_after, and latency runs from the dial to the decoded answer. A response code above 15 is read through the EDNS record. The judgement follows the spec: NOERROR with an answer of the asked type, every expected value in the answer set in the SDK's canonical form, or NXDOMAIN when the check expects it. A failure's error starts with dns_rcode, dns_mismatch, dns_no_answer or dns_transport, and the result carries the response code and at most 16 answers of at most 255 bytes. The agent advertises dns in probe_methods, and a change to the question restarts the check. The SDK pin moves to the S5a branch commit (lattice-sdk #45); it is re-pinned after that merges. Tested: stub resolvers per transport covering pass, mismatch, NXDOMAIN expected and received, SERVFAIL, truncated UDP to TCP, a DoH 500, a certificate for another name, a slow resolver, a body over 64 KiB and a private resolver; go test -race on prober and cmd; gosec and govulncheck.
The release carries the dns check of design 32 S5a (lattice-node-agent #45): DoH, DoT, UDP and TCP resolvers, the destination rule on the resolved address, the certificate expiry of DoH and DoT, and the judgement and failure codes the control plane shows. No compatibility floor moves; a server before S5a never hands the agent a dns check. The SDK pin is the S5a branch commit; it moves to the merged lattice-sdk commit before this is tagged.
…t failure A review found that only the UDP path acted on the truncation bit: a truncated answer over TCP, DoT or DoH, or a second one after the TCP retry, reached the judgement with an empty response code and failed as dns_rcode with no code. It now fails as dns_transport, "the response is truncated". The same pass tightens three smaller things. A response that echoes a question must echo the one asked, so an answer carrying the right ID for another name is refused. A DoH answer's ID is not judged, since HTTP binds it to its request and RFC 8484 sends 0. The TCP retry goes to the address the truncated UDP answer came from. A reported answer drops invalid UTF-8 before it is cut, at a character boundary, so it never grows past 255 bytes. Tested: the new cases fail before the change; go test -race ./internal/prober/; gosec.
…elease-0.3.10-alpha.10
dialJudged's share of the deadline per address becomes addrContext, so the UDP exchange can try addresses on the same terms, and exchangeDoH builds its client through dohClient, the seam the DNS tests use to pin that a DoH request dials only its target. No behavior changes.
The DoH and resolver protections were covered only through the http check's tests, which would not notice the DNS probe stepping around the shared transport. Four tests now pin them on the DNS path: a DoH 3xx to loopback, a private range or the metadata service is reported and not followed; a proxy in the environment is ignored (the transport is checked too, since net/http reads the environment once per process); a DoH request for any host but the target is refused before a dial; and a resolver name with one private address among public ones is refused before any query, in either order and over every transport. Tested: each test fails with its protection removed (CheckRedirect dropped, Proxy set to ProxyFromEnvironment, the host check disabled, only the first address judged) and passes with it in place.
A DoH answer with the wrong content type echoed the whole header, so a resolver could put up to 64 KiB of its own text into the result's error, which every node ships to the control plane on each run and the server stores. The error now names only the parsed media type, cut to 64 bytes. The other places a resolver's text reached the error are bounded the same way: a TLS failure names the host asked for and at most three of the certificate's names, 64 bytes each, instead of the x509 error's full list; a transport error, which can quote the resolver's bytes (a garbled HTTP status line, HTTP/2 GOAWAY debug data), is cut to 160 bytes; and the whole error is cut to 512 bytes, the server's bound on a stored error, so a node never sends text the server would cut. Reason only ever carries constants, decode errors are fixed strings, and answers already pass through dnsReported's bounds. Tested: TestDNSResolverTextInErrorsIsBounded failed before the fix (a 61513-byte error) and passes after.
…r silent exchangeUDP dialed only the first judged address, so a healthy resolver whose first address is in a family the node cannot reach, or simply does not answer, read as a timeout. It now asks the addresses in turn, each for its share of the run's time on the same terms as dialJudged (addrContext), as TCP, DoT and DoH already fall through. An answer, right or wrong, ends the exchange at that address; a wrong answer is not a reason to ask another. A truncated answer is asked again over TCP of the address that sent it, which is no longer always the first. Tested: TestDNSUDPTriesTheNextAddress failed before the fix on the unreachable, silent and truncated cases and passes after; the wrong answer case pins that the second address is never asked.
The UDP, TCP and DoT exchanges set the connection's deadline from the context but did not watch its cancellation, so a run cancelled at shutdown sat in its read until the check's timeout, up to the full timeout per check. bindConn replaces setDeadline: it keeps the deadline and closes the connection from context.AfterFunc when the context is cancelled. A deadline that passes is still left to the connection's own timeout, so a slow resolver reads as a timeout rather than a closed connection, and a cancelled run now says it was cancelled instead of timed out. DoH already followed its request's context. Tested: TestDNSCancelEndsTheRun failed before the fix (a TCP run cancelled after 200 ms took 20 s) and passes after over UDP, TCP, DoT and DoH; go test -race on internal/prober and cmd/lattice-agent, gosec (67 files, 0 issues) and govulncheck pass.
…elease-0.3.10-alpha.10
…error bounds The alpha.10 entry said one query per run and nothing about error size or cancellation; agent #45's review fixes changed all three.
Over TCP, DoT and DoH only an address that cannot be connected to falls through; a connected one that stays silent ends the run at its timeout.
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
Version bump and CHANGELOG for v0.3.10-alpha.10: the dns check method of design 32 S5a (#45).
cmd/lattice-agent/main.goversion andmain_test.go, as #44 did.Stacked on #45: this branch starts from
feature/20261025_s5a-dns-check, so until #45 merges the diff here shows both. Merge #45 first.Before tagging: #45 pins the SDK to the S5a branch commit (
v0.2.24-0.20261025003326-6485e4abe7b9, lattice-sdk #45). Re-pin to the merged lattice-sdk commit first; the CHANGELOG names lattice-sdk #45, not the pseudo-version, so it stays right. This PR does not tag and creates no release.No compatibility floor moves. A server before S5a drops
dnsfrom probe methods and never hands the agent a dns check; a node on alpha.9 or older readsagent_too_oldfor a dns check until it updates through its own approval.Test plan
go test ./cmd/lattice-agent/;scripts/check-release-workflow.sh.go test -race -cover ./..., gosec guard, release workflow check).-versionprints 0.3.10-alpha.10,-compat-jsonfloors unchanged, binaries built with go1.26.10.