feat: discover Diameter peers through DNS

Merged
GO
15d ago
+8502-39

RFC 6733 §5.2 requires every Diameter implementation to support DNS
discovery as well as manual configuration; go-diameter had only manual
configuration.

  • The new module github.com/gomaja/go-diameter/dnsdiam discovers peers
    for a realm and application: S-NAPTR with the Diameter service and
    transport tags of RFC 6408 (RFC 3958, updated by RFC 8553), SRV under
    the realm only when NAPTR records are absent, RFC 2782 priority and
    weighted ordering, and explicit A and AAAA lookups. Each candidate
    expires at the earliest TTL along its chain, and TTL 0 is never cached.
  • DNS queries go through Codeberg's miekg/dns behind dnsdiam's own
    Resolver interface, with truncation-to-TCP retry, response and question
    validation, bounded retries, resolv.conf or explicit nameservers, and
    no search-list expansion.
  • peer.Manager gains discovered-peer leases with refresh and release,
    dynamic routes that keep the discovery ranking per realm and
    application, and expiry enforced at routing, selection, reconnect and
    just before sending. Static configuration is unchanged, and the core
    module imports no DNS package.
  • A discovered peer is admitted only after certificate checks along the
    naming chain, realm and application authorisation, and Origin-Host and
    Origin-Realm checks on CER and CEA (RFC 6733 §§5.2, 13.1-13.2). TLS is
    the default; plaintext needs explicit configuration.
  • A dial helper connects plain Dial users to discovered candidates.

scripts/check.sh validates the new module, runs the symbol and package
vulnerability scans with tests included, and allows exactly one
module-level finding: GO-2026-5932, the permanent advisory against
golang.org/x/crypto/openpgp, which enters the module graph through the
DNS client's x/crypto requirement. The check fails if any module imports
an openpgp package on any platform or build tag.

Fixes #100

Validation

  • make check passes locally for all three modules: format, test (Go 1.27.2
    and 1.26.9), race, vet, lint, vuln, windows, secrets and codeql.
  • Discovery tests run against fake resolvers, clocks and random sources,
    and against an ephemeral authoritative DNS server on loopback over UDP
    and TCP, with no external lookups: tags, flags, backtracking, SRV
    ordering and weights, address chains, TTL expiry and the absence/failure
    distinction.
  • Manager tests cover lease ownership, ordered dynamic routes, expiry at
    each decision point, TLS refresh followed by reconnect, permuted address
    answers and static reconnect after a dial races its deadline; mutating
    any of these fails a named test.
  • The vulnerability gate has its own tests, including negative vectors for
    extra findings, duplicate JSON keys, malformed SBOMs and openpgp imports
    under other platforms and build tags, plus fuzzing.

The modules move together: install github.com/gomaja/go-diameter@main with
dnsdiam@main, since dnsdiam uses Manager APIs added here.


Summary by cubic

Implements RFC 6733 §5.2 DNS peer discovery for go-diameter, which previously only supported manual configuration.

  • Adds the dnsdiam module: S-NAPTR discovery using RFC 6408 application/transport tags, SRV fallback under the realm only when NAPTR records are absent, RFC 2782 priority/weight ordering, and explicit A/AAAA lookups. Candidates expire at the earliest TTL along their chain; TTL 0 is never cached. DNS stays out of the core module.
  • peer.Manager gains discovered-peer leases with refresh and release, dynamic routes that preserve DNS ranking per realm and application, and expiry enforced at routing, selection, reconnect, and just before sending. Static configuration is unchanged.
  • A discovered peer is admitted only after certificate checks along the naming chain, realm and application authorization, and Origin-Host/Origin-Realm validation on CER and CEA. TLS is the default; plaintext requires explicit configuration.
  • Adds a dial helper that connects plain Dial users to discovered candidates.
  • scripts/check.sh now covers the new module and adds a vulnerability gate that allows exactly one module-level finding (GO-2026-5932, the permanent advisory against golang.org/x/crypto/openpgp) and fails if any module imports an openpgp package on any platform or build tag.

Fixes #100.

Migration

  • Install github.com/gomaja/go-diameter@main together with dnsdiam@main; the discovery module uses the new Manager lease API.