# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview RouteDNS is a composable DNS stub resolver, proxy and router written in Go. It builds processing pipelines from four component types (listeners, resolvers, groups/modifiers, routers) configured via TOML files. ## Build & Test Commands ```bash # Build go build -o cmd/desync/ ./cmd/routedns # Run all tests go test ./... # Run a single test go test -run TestCacheLookupAndExpiry ./... # Run tests in a specific package go test ./dnssec/ # Run with race detector go test -race ./... # Run the binary routedns config.toml ``` There is no Makefile or linter configuration. CI uses GitHub Actions with CodeQL analysis only. ## Architecture ### Core Abstraction Every component in the pipeline implements the `Resolver` interface (`resolver.go`): ```go type Resolver interface { Resolve(*dns.Msg, ClientInfo) (*dns.Msg, error) fmt.Stringer } ``` This single interface is implemented by clients, groups, modifiers, and routers alike, enabling arbitrary composition. ### Pipeline Flow ``` Listeners (receive DNS queries over UDP/TCP/DoT/DoH/DoQ/DTLS/ODoH) ↓ Routers (route based on query name, type, source IP, time, etc.) ↓ Groups/Modifiers (cache, blocklist, load-balance, transform) ↓ Resolvers/Clients (forward to upstream DNS servers) ``` ### Component Types - **Listeners** (`Listener` interface in `listener.go`): Entry points that accept DNS queries. Each protocol has its own file (e.g., `dohlistener.go`, `dotlistener.go`, `doqlistener.go`). - **Clients/Resolvers**: Forward queries upstream. Each protocol is in its own file (`dnsclient.go` for UDP/TCP, `dotclient.go`, `dohclient.go`, `doqclient.go`, `dtlsclient.go`, `odohclient.go`). - **Groups/Modifiers** (~30 types): Wrap one or more resolvers to add behavior — caching (`cache.go`), blocklists (`blocklist-v2.go`), load-balancing (`round-robin.go`, `failrotate.go`, `fastest.go`), rate limiting (`rate-limiter.go`), query/response modification, etc. - **Routers** (`router.go`): Conditional routing based on query properties (name regex, type, source IP, time of day, etc.). Routes evaluated in order; first match wins. ### Configuration System TOML-based configuration defined in `cmd/routedns/config.go`. Four top-level sections: `[listeners]`, `[resolvers]`, `[groups]`, `[routers]`. Component instantiation in `cmd/routedns/resolver.go` uses a DAG (`github.com/heimdalr/dag`) to resolve dependencies bottom-up, preventing circular references. Multiple config files can be provided as arguments and are merged. ### Key Patterns - **Go package name**: `rdns` (import as `github.com/folbricht/routedns`) - **Composition via Resolver interface**: Groups/modifiers wrap inner resolvers, creating decorator chains - **Options structs**: Constructors take `*XxxOptions` structs (e.g., `CacheOptions`, `DNSClientOptions`) - **Metrics**: Components export metrics via `expvar` using the pattern `routedns...` - **Graceful shutdown**: `onClose` functions registered globally, triggered on SIGTERM/SIGINT - **Blocklist databases**: `BlocklistDB` interface with implementations for domains, regex, hosts, CIDR, GeoIP, ASN, MAC formats ### Testing Tests use a `TestResolver` mock (returns the query as-is or a configured response). Test files live alongside source files. Some tests require network access (DoH/DoT/DoQ client tests connect to real servers).