dnsimple/erldns
59.9
Adequate · 23 September 2026
8k
lines of production code
Erlang
primary language
5
measurements over time
What this system is
This system is a high-performance, embeddable DNS server built on Erlang/OTP that manages zone data and processes queries through a modular, asynchronous pipeline. It supports both UDP and TCP listeners with advanced congestion control and load shedding to maintain stability under heavy load, while offering a comprehensive HTTP Admin API for zone management and monitoring. The platform includes robust DNSSEC support, parallel zone loading, and extensive tooling for testing and simulation.
How it got here
2011–2012 — OTP refactoring and API stabilization
4 changes.
The project underwent a significant architectural shift by replacing legacy UDP server modules with a structured OTP application, exposing controlled listener management and configuration interfaces. This period also involved hardening the public API by removing internal DNS record definitions from headers and standardizing the build system on rebar3. Support for testing and simulation was enhanced through the addition of a fake DNS responder and Scapy examples.
2025–2026 — DNS server architecture overhaul
10 changes.
This period focused on a comprehensive rewrite of the DNS server's core architecture, introducing a pluggable asynchronous packet pipeline and a high-performance ETS-based zone cache. Significant improvements were made to listener stability through new congestion control mechanisms like CoDel and CUBIC, alongside a new HTTP-based Admin API for zone management and monitoring.
Features
Add documentation and sample zone files for DNSSEC support
Added a new ZONES.md guide explaining how to configure and load DNS zones in JSON or standard zonefile formats, including support for contexts and DNSSEC keys (RSA, ECDSA, Ed25519, Ed448). Included sample zone files (e.g., example.com.json) demonstrating various record types and DNSSEC key configurations to help users bootstrap and test their DNS setups.
priv/zones · high confidence
Added fake DNS responder and Scapy test examples
The \priv\ directory now includes \erldns\_fake\_responder.erl\, a new module that generates mock DNS responses for a wide range of record types (including A, AAAA, MX, TXT, DNSSEC, and others) to support testing or simulation scenarios. Additionally, \priv/scapy.txt\ has been added, providing Python Scapy script examples for constructing and sending raw DNS packets to a local server on port 8053, covering scenarios such as basic queries, truncated messages, and error conditions.
priv · high confidence
Introduce pluggable packet pipeline with asynchronous worker pool
DNS query processing is now handled by a configurable, sequential pipeline of modular pipe handlers (such as \erldns\_questions\, \erldns\_resolver\, and \erldns\_dnssec\) rather than a monolithic handler. This architecture allows for non-blocking, asynchronous execution of blocking operations via a dedicated \erldns\_async\_pool\ that uses CoDel for queue management, ensuring that listener workers are not stalled by slow tasks. The system includes built-in support for query throttling, packet caching, EDNS Extended DNS Errors (RFC 8914), and DNSSEC signing with NSEC type-mapper extensions, all orchestrated through a standardized \erldns\_pipeline\ behavior.
src/pipes · high confidence
New Admin API for DNS management and monitoring
This release introduces a new HTTP-based Admin API (default port 8083) that allows administrators to inspect and manage DNS zones and listener queues. The API provides endpoints to list all cached zones and their versions, retrieve detailed record information for specific zones (with an optional metadata-only mode), and delete zones from the cache. It also supports resetting all listener queues via a DELETE request on the root path. The API includes built-in Basic Authentication, configurable TLS support, and the ability to register custom middleware modules and additional routes for extensibility.
src/admin · high confidence
New zone generation and query generation scripts
Added a standalone Erlang escript (\scripts/generate\_zone.escript\) for generating JSON zone files compatible with erldns, supporting configurable record counts, parallel generation, and DNSSEC signing with multiple algorithms (RSA, ECDSA, Ed25519, Ed448). Also added \scripts/generate\_kxdpgun.escript\ to convert these JSON zone files into kxdpgun query format, and a BSD-specific CI script (\scripts/ci/bsd.sh\) that enforces OTP 28 or newer for socket tests.
scripts · high confidence
Behavioural changes
DNS message record definitions removed from public include headers
The \include/nsrecs.hrl\ file, which previously exposed internal DNS protocol record definitions (such as \header\, \question\, and \message\) to external code, has been deleted. These definitions are no longer part of the public include interface, indicating a shift in how DNS message structures are handled internally versus externally.
include · high confidence
New TCP listener implementation with concurrency control and pipeline suspension
The TCP listener component has been replaced with a new implementation that introduces configurable concurrency limits (max\_concurrent\_queries) to prevent resource exhaustion, and supports pipeline suspension for non-blocking asynchronous operations. The new architecture includes dedicated modules for protocol handling, configuration, and request processing, featuring specific timeout controls (ingress, idle, request) and telemetry for dropped or delayed requests.
src/listeners/tcp · high confidence
New UDP listener implementation with load shedding and overrun reporting
The UDP listener has been replaced with a new architecture that introduces explicit load shedding and better observability. Incoming UDP packets are now managed by a worker pool (wpool) that enforces a configurable ingress timeout; when the system is under stress, excess requests are dropped and reported via telemetry and logs, including the raw payload in case of decode crashes. The acceptor layer now uses a cubic congestion control algorithm to dynamically adjust batch processing based on scheduler utilization, preventing overload. Additionally, the new implementation provides detailed overrun metrics, allowing operators to monitor and react to backpressure events more effectively.
src/listeners/udp · high confidence
New congestion control and queue management for UDP listeners
UDP listeners now include CoDel queue management (erldns\_codel.erl) to prevent bufferbloat and smarter congestion control algorithms (erldns\_cubic.erl) to adapt admission rates based on system stress. These changes improve network stability and reduce latency under heavy load by actively managing packet drops and adjusting processing speeds in response to congestion signals.
src/listeners · high confidence
Parallel zone loading with strict mode validation
The zone loading subsystem now supports parallel loading of zone files (JSON and BIND zonefile formats) via a new gen\_server-based worker architecture. This change introduces a 'strict' configuration mode: when enabled, the loader will fail the entire load operation if any individual zone file or key file contains errors or is missing, rather than silently skipping them. It also adds validation for configuration parameters such as format, timeout, and keys path, ensuring that invalid inputs are caught early during startup.
src/zones/load · high confidence
Project restructure and documentation overhaul
The repository has been restructured with a comprehensive documentation update, including new files for agent instructions (AGENTS.md), benchmarking (BENCHMARKING.md), design decisions (DESIGN.md), and a detailed changelog (CHANGELOG.md). The build system has been standardized on rebar3, with a new Makefile and rebar.config replacing legacy build artifacts like the Emakefile. Configuration is now managed via erldns.example.config, and linting/formatter rules have been added for markdown and YAML files. The project now requires Erlang/OTP 28 or newer and includes a Procfile for process management.
(repo-wide) · high confidence
Reimplemented zone loading, caching, and codec system
The zone management subsystem has been completely rewritten to improve performance, correctness, and extensibility. The new \erldns\_zone\_cache\ introduces a more efficient ETS-based storage structure with dedicated tables for zones, typed records, and sync counters, along with added telemetry events for zone put/delete operations. Zone data encoding and decoding are now handled by a unified, extensible codec system (\erldns\_zone\_codec\, \erldns\_zone\_encoder\, \erldns\_zone\_decoder\) that supports custom JSON parsers via registered modules and context-based record filtering. The zone loader (\erldns\_zones\) now supports both JSON and standard zone file formats with parallel loading capabilities, configurable timeouts, and strict error handling modes.
src/zones · high confidence
Replaced legacy UDP server with OTP application and configurable listeners
The legacy \server\ and \unpack\ modules have been removed and replaced with a proper OTP application structure (\erldns\_app\, \erldns\_sup\). The new implementation exposes \erldns:start\_listeners/0\ and \erldns:stop\_listeners/0\ to allow embedding applications to control when DNS listeners start, supporting an \autostart\_listeners\ configuration option. It also introduces \erldns\_config\ for cross-platform socket options (handling IPv6 dual-stack and \SO\_REUSEPORT\ nuances on FreeBSD/Linux/Windows) and exports \keyset\ and \zone\ types for external use.
src · high confidence
Test coverage
Comprehensive Common Test suite for DNS server components
Added a new Common Test (CT) suite covering the admin endpoint, AXFR transfers, configuration parsing, DNSSEC validation, EDNS/Extended Errors, listener behavior (UDP/TCP/TLS), packet caching, and pipeline execution. The suite includes a test helper module for managing peer nodes and ports, an example middleware for admin API testing, and TLS certificate/key fixtures for listener tests.
test · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.
Score
- CAI 45 → 60 (+14.8)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 92 → 99 (+6.4)
- Architecture 99 → 91 (-7.9)
- Maturity 57 → 67 (+10.0)
- Readiness 70 → 82 (+12.3)
- Security 18 → 40 (+22.3)
Resolved (29)
- Coverage not included — suite not readable by the collector
- Dependency hygiene not measured — dependency manifest found but not parsed for hygiene
- FileTooLong: pipes/erldns_pipeline.erl (src/pipes/erldns_pipeline.erl)
- FileTooLong: pipes/erldns_resolver.erl (src/pipes/erldns_resolver.erl)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- …and 9 more
New (36)
- Coverage not measured — no coverage collector is wired up
- Documentation: no installation or build instructions (README.md)
- Documentation: no usage examples (README.md)
- Duplicated block (13 lines × 2) (src/listeners/udp/erldns_proto_udp.erl)
- Duplicated block (7 lines × 2) (src/admin/erldns_admin_root_handler.erl)
- Duplicated block (7 lines × 2) (src/listeners/tcp/erldns_proto_tcp_config.erl)
- Duplicated block (8 lines × 2) (src/listeners/tcp/erldns_proto_tcp_request.erl)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- High: security finding (details withheld)
- …and 16 more
Changes since last survey
- 15 commits — 15 feature/other, 0 fixes
By area
- (root) — 9 commits
- .github/workflows — 3 commits
- src/pipes — 2 commits
- src/listeners — 1 commit
Notable commits
- change: Bump cross-platform-actions/action in the actions-patch-minor group (#365)
- change: Bump cross-platform-actions/action in the actions-patch-minor group (#368)
- change: Bump cross-platform-actions/action in the actions-patch-minor group (#372)
- change: Handle DNSSEC at delegation points (#371)
- change: Reach the custom decoders without raising through dns_json (#364)
- change: Release v11.2.2
- change: Release v11.2.4
- change: Report when the async pool finishes a suspended continuation
- change: Report wpool's overrun details from the UDP listener (#373)
- change: Require OTP 28 or newer (#367)
- change: Serve negative answers with the RFC 2308 negative TTL (#370)
- change: Stop killing async pool workers that overrun
- change: Update dependencies (#366)
- change: Update dependencies (#369)
- change: Upgrade dns_erlang
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
dnsimple/erldns was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 23 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit cc96ba2d305445e54f84e75dd9cd7a9949e27f6f — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-955b9cee9818.