initial implementation #1

Open
opened 2026-03-23 09:29:45 +00:00 by despiegk · 4 comments
Owner

Full Spec — Managed DNS Daemon (Port 53, SQLite, OpenRPC, Role-Pattern Auth)


0. Purpose

Build a minimal, production-grade DNS daemon that:

  • Listens on UDP + TCP port 53 (IPv4 + IPv6)
  • Answers authoritative DNS queries from a SQLite-backed zone store
  • Supports forwarding (standard DNS + peer nodes)
  • Exposes a Unix Domain Socket (UDS) OpenRPC API
  • Implements stateless, role-pattern authorization
  • Allows runtime reconfiguration (listeners, zones, forwarders)
  • Provides typed querying via OpenRPC in addition to DNS wire protocol

The system is a managed DNS server, not just a stub resolver.


1. High-Level Architecture

[DNS Client] ──UDP/TCP:53──▶ [DNS Engine]
                               │
                               ▼
                         [Resolver Core]
                         /      |      \
                [Zones/DB]  [Cache]  [Forwarders]
                               │
                               ▼
                      [SQLite (single source)]
                               ▲
                               │
                    [OpenRPC over UDS Control Plane]
                               ▲
                               │
                         [Auth Proxy]
                         (injects claims)

2. Core Features

2.1 DNS Serving

  • UDP + TCP on port 53
  • IPv4 and IPv6
  • Authoritative zones
  • Standard record types
  • Wildcard support
  • Proper DNS response codes

2.2 Management

  • OpenRPC over UDS only

  • Full CRUD for:

    • zones
    • records
    • forwarders
    • listeners
  • Runtime updates without restart

2.3 Storage

  • SQLite as single source of truth
  • Typed record storage
  • Persistent configuration

2.4 Forwarding

  • Standard DNS forwarders
  • Peer managed nodes (same daemon)
  • Priority + fallback
  • Optional system resolver fallback

2.5 Authorization

  • Stateless
  • Role-pattern matching
  • Zone-level enforcement only

3. Authorization Model (FULL WORKFLOW)

3.1 Principle

  • The daemon does not authenticate
  • It trusts incoming claims
  • Claims are injected by a proxy layer

3.2 Request Flow

Client → Proxy → inject claims → DNS Daemon → Authorization → Execute

3.3 Claims (Input)

Each OpenRPC request includes:

{
  "claims": "admin,users.kristof,zone.example.write"
}
  • comma-separated
  • flat strings
  • dot-separated semantic convention

3.4 Rules (Stored per Zone)

Each zone has:

"rules": ["admin.*", "zone.example.*", "users.kristof"]

3.5 Authorization Decision

A request is allowed if:

ANY(claim matches ANY(rule))

3.6 Matching Semantics

Rules:

  • * matches any suffix
  • dot-separated hierarchical matching

Examples

Rule Claim Result
admin.* admin.john
users.* users.kristof
zone.example.* zone.example.write
zone.* zone.example.write
* anything

3.7 Matching Algorithm

match(rule, claim):
  r = split(rule, ".")
  c = split(claim, ".")

  for i in range(len(r)):
    if r[i] == "*":
      return true
    if i >= len(c):
      return false
    if r[i] != c[i]:
      return false

  return len(r) == len(c)

3.8 Enforcement Scope

Authorization is checked:

👉 ONLY at zone level

Never per record.


3.9 Operations Requiring Authorization

  • zone.create
  • zone.update
  • zone.delete
  • zone.enable/disable
  • record.create/update/delete
  • forwarder.create/update/delete
  • listener.create/update/delete

3.10 Public Operations

No auth required:

  • DNS queries (UDP/TCP)

  • OpenRPC:

    • query.*
    • zone.list / get
    • record.list / get

3.11 Default Behavior

  • If no rules → deny mutations
  • If rules exist → must match

4. DNS Engine

4.1 Query Flow

1. Receive query
2. Find best matching zone
3. If zone exists AND responding enabled:
     try local records
4. If not found:
     try forwarders (priority order)
5. If forwarders fail:
     try system resolvers (optional)
6. Return DNS response

4.2 Response Codes

Must support:

  • NOERROR
  • NXDOMAIN
  • SERVFAIL
  • REFUSED

4.3 Record Types (Required)

  • A, AAAA
  • CNAME
  • NS
  • MX
  • TXT
  • SRV
  • PTR
  • SOA
  • CAA
  • NAPTR
  • TLSA
  • DNSKEY
  • DS
  • SSHFP
  • LOC
  • SPF
  • HINFO
  • RP

4.4 TTL Handling

  • TTL stored per record
  • TTL respected in responses
  • cache honors TTL

5. Zones

5.1 Structure

Each zone:

  • name
  • enabled (responding)
  • rules (auth)
  • records
  • metadata

5.2 Matching

Longest suffix match:

api.dev.example.com → dev.example.com > example.com

5.3 Zone Operations

  • create
  • update
  • delete
  • enable/disable responding
  • list
  • get
  • import/export

6. Records

6.1 Fields

  • id
  • zone_id
  • name
  • type
  • class
  • ttl
  • typed data
  • enabled

6.2 Typed Storage

Examples:

  • A → IPv4
  • AAAA → IPv6
  • MX → preference + exchange
  • SRV → priority/weight/port/target
  • SOA → full structure

6.3 Operations

  • create/update/delete

  • enable/disable

  • list by:

    • zone
    • name
    • type

7. Forwarders

7.1 Types

Standard DNS

  • IP + port
  • UDP/TCP

Peer Node

  • OpenRPC endpoint
  • same protocol

7.2 Behavior

  • priority-based
  • fallback chain
  • timeout + retry

7.3 System Resolver Fallback

Optional:

  • read system DNS config
  • try those resolvers

7.4 Policy Modes

  • local_only
  • local_then_forward (default)
  • forward_only

8. Listeners

8.1 Default

  • UDP 53 (IPv4 + IPv6)
  • TCP 53 (IPv4 + IPv6)

8.2 Configurable via OpenRPC

  • protocol (UDP/TCP)
  • address
  • port
  • enable/disable

8.3 UDS

  • always enabled
  • used for OpenRPC

9. OpenRPC API

9.1 Transport

  • Unix Domain Socket
  • JSON-RPC 2.0

9.2 Modules

  • zones
  • records
  • forwarders
  • listeners
  • queries
  • system
  • health

9.3 Example Methods

Zones

  • zone.list
  • zone.get
  • zone.create
  • zone.update
  • zone.delete
  • zone.enable
  • zone.disable

Records

  • record.list
  • record.create
  • record.update
  • record.delete

Forwarders

  • forwarder.list
  • forwarder.create_dns
  • forwarder.create_peer
  • forwarder.update
  • forwarder.delete

Listeners

  • listener.list
  • listener.create
  • listener.update
  • listener.delete

Queries

  • query.resolve
  • query.a / aaaa / mx / txt / ns / srv / soa / ptr
  • query.zone_dump

10. SQLite Schema

Tables

  • zones
  • records
  • forwarders
  • listeners
  • global_config

Zones Table

id
name UNIQUE
enabled
rules TEXT (JSON array)

Records Table

id
zone_id
name
type
ttl
data (JSON)
enabled

11. Runtime Behavior

11.1 Dynamic Updates

No restart required for:

  • zones
  • records
  • forwarders
  • listeners

11.2 Cache

  • TTL-based
  • positive + optional negative caching

11.3 Logging

  • queries
  • forwarders
  • auth decisions
  • config changes

12. Networking

12.1 Protocols

  • UDP DNS
  • TCP DNS (length-prefixed)

12.2 IPv4 + IPv6 required


13. Validation

Must validate:

  • zone names
  • record formats
  • TTL ranges
  • forwarder endpoints
  • listener configs
  • rule syntax

14. Default Bootstrap

On first run:

  • create DB
  • create listeners (53 UDP/TCP)
  • seed forwarders (8.8.8.8, 1.1.1.1)
  • create empty config

15. Acceptance Criteria

DNS

  • resolves A/AAAA/MX/etc
  • works on UDP + TCP
  • IPv4 + IPv6

Auth

  • rules enforced
  • wildcard matching correct
  • mutations blocked without match

API

  • OpenRPC fully functional
  • dynamic config works

Persistence

  • SQLite persists everything

16. Final Design Philosophy

This system is:

  • minimal
  • stateless in auth
  • extensible
  • infrastructure-ready
  • composable with external identity systems

17. SKILLS to be used to implement this

/hero_crates_best_practices_check
/hero_proc_service_selfstart
/hero_sockets

# **Full Spec — Managed DNS Daemon (Port 53, SQLite, OpenRPC, Role-Pattern Auth)** --- ## 0. Purpose Build a **minimal, production-grade DNS daemon** that: * Listens on **UDP + TCP port 53** (IPv4 + IPv6) * Answers **authoritative DNS queries** from a **SQLite-backed zone store** * Supports **forwarding** (standard DNS + peer nodes) * Exposes a **Unix Domain Socket (UDS) OpenRPC API** * Implements **stateless, role-pattern authorization** * Allows **runtime reconfiguration** (listeners, zones, forwarders) * Provides **typed querying via OpenRPC** in addition to DNS wire protocol The system is a **managed DNS server**, not just a stub resolver. --- ## 1. High-Level Architecture ```text [DNS Client] ──UDP/TCP:53──▶ [DNS Engine] │ ▼ [Resolver Core] / | \ [Zones/DB] [Cache] [Forwarders] │ ▼ [SQLite (single source)] ▲ │ [OpenRPC over UDS Control Plane] ▲ │ [Auth Proxy] (injects claims) ``` --- ## 2. Core Features ### 2.1 DNS Serving * UDP + TCP on port 53 * IPv4 and IPv6 * Authoritative zones * Standard record types * Wildcard support * Proper DNS response codes ### 2.2 Management * OpenRPC over UDS only * Full CRUD for: * zones * records * forwarders * listeners * Runtime updates without restart ### 2.3 Storage * SQLite as **single source of truth** * Typed record storage * Persistent configuration ### 2.4 Forwarding * Standard DNS forwarders * Peer managed nodes (same daemon) * Priority + fallback * Optional system resolver fallback ### 2.5 Authorization * Stateless * Role-pattern matching * Zone-level enforcement only --- # 3. Authorization Model (FULL WORKFLOW) ## 3.1 Principle * The daemon **does not authenticate** * It **trusts incoming claims** * Claims are injected by a **proxy layer** --- ## 3.2 Request Flow ```text Client → Proxy → inject claims → DNS Daemon → Authorization → Execute ``` --- ## 3.3 Claims (Input) Each OpenRPC request includes: ```json { "claims": "admin,users.kristof,zone.example.write" } ``` * comma-separated * flat strings * dot-separated semantic convention --- ## 3.4 Rules (Stored per Zone) Each zone has: ```json "rules": ["admin.*", "zone.example.*", "users.kristof"] ``` --- ## 3.5 Authorization Decision A request is allowed if: ```text ANY(claim matches ANY(rule)) ``` --- ## 3.6 Matching Semantics ### Rules: * `*` matches any suffix * dot-separated hierarchical matching ### Examples | Rule | Claim | Result | | -------------- | ------------------ | ------ | | admin.* | admin.john | ✅ | | users.* | users.kristof | ✅ | | zone.example.* | zone.example.write | ✅ | | zone.* | zone.example.write | ✅ | | * | anything | ✅ | --- ## 3.7 Matching Algorithm ```text match(rule, claim): r = split(rule, ".") c = split(claim, ".") for i in range(len(r)): if r[i] == "*": return true if i >= len(c): return false if r[i] != c[i]: return false return len(r) == len(c) ``` --- ## 3.8 Enforcement Scope Authorization is checked: 👉 **ONLY at zone level** Never per record. --- ## 3.9 Operations Requiring Authorization * zone.create * zone.update * zone.delete * zone.enable/disable * record.create/update/delete * forwarder.create/update/delete * listener.create/update/delete --- ## 3.10 Public Operations No auth required: * DNS queries (UDP/TCP) * OpenRPC: * query.* * zone.list / get * record.list / get --- ## 3.11 Default Behavior * If no rules → deny mutations * If rules exist → must match --- # 4. DNS Engine ## 4.1 Query Flow ```text 1. Receive query 2. Find best matching zone 3. If zone exists AND responding enabled: try local records 4. If not found: try forwarders (priority order) 5. If forwarders fail: try system resolvers (optional) 6. Return DNS response ``` --- ## 4.2 Response Codes Must support: * NOERROR * NXDOMAIN * SERVFAIL * REFUSED --- ## 4.3 Record Types (Required) * A, AAAA * CNAME * NS * MX * TXT * SRV * PTR * SOA * CAA * NAPTR * TLSA * DNSKEY * DS * SSHFP * LOC * SPF * HINFO * RP --- ## 4.4 TTL Handling * TTL stored per record * TTL respected in responses * cache honors TTL --- # 5. Zones ## 5.1 Structure Each zone: * name * enabled (responding) * rules (auth) * records * metadata --- ## 5.2 Matching Longest suffix match: ```text api.dev.example.com → dev.example.com > example.com ``` --- ## 5.3 Zone Operations * create * update * delete * enable/disable responding * list * get * import/export --- # 6. Records ## 6.1 Fields * id * zone_id * name * type * class * ttl * typed data * enabled --- ## 6.2 Typed Storage Examples: * A → IPv4 * AAAA → IPv6 * MX → preference + exchange * SRV → priority/weight/port/target * SOA → full structure --- ## 6.3 Operations * create/update/delete * enable/disable * list by: * zone * name * type --- # 7. Forwarders ## 7.1 Types ### Standard DNS * IP + port * UDP/TCP ### Peer Node * OpenRPC endpoint * same protocol --- ## 7.2 Behavior * priority-based * fallback chain * timeout + retry --- ## 7.3 System Resolver Fallback Optional: * read system DNS config * try those resolvers --- ## 7.4 Policy Modes * local_only * local_then_forward (default) * forward_only --- # 8. Listeners ## 8.1 Default * UDP 53 (IPv4 + IPv6) * TCP 53 (IPv4 + IPv6) --- ## 8.2 Configurable via OpenRPC * protocol (UDP/TCP) * address * port * enable/disable --- ## 8.3 UDS * always enabled * used for OpenRPC --- # 9. OpenRPC API ## 9.1 Transport * Unix Domain Socket * JSON-RPC 2.0 --- ## 9.2 Modules * zones * records * forwarders * listeners * queries * system * health --- ## 9.3 Example Methods ### Zones * zone.list * zone.get * zone.create * zone.update * zone.delete * zone.enable * zone.disable --- ### Records * record.list * record.create * record.update * record.delete --- ### Forwarders * forwarder.list * forwarder.create_dns * forwarder.create_peer * forwarder.update * forwarder.delete --- ### Listeners * listener.list * listener.create * listener.update * listener.delete --- ### Queries * query.resolve * query.a / aaaa / mx / txt / ns / srv / soa / ptr * query.zone_dump --- # 10. SQLite Schema ## Tables * zones * records * forwarders * listeners * global_config --- ## Zones Table ```sql id name UNIQUE enabled rules TEXT (JSON array) ``` --- ## Records Table ```sql id zone_id name type ttl data (JSON) enabled ``` --- # 11. Runtime Behavior ## 11.1 Dynamic Updates No restart required for: * zones * records * forwarders * listeners --- ## 11.2 Cache * TTL-based * positive + optional negative caching --- ## 11.3 Logging * queries * forwarders * auth decisions * config changes --- # 12. Networking ## 12.1 Protocols * UDP DNS * TCP DNS (length-prefixed) --- ## 12.2 IPv4 + IPv6 required --- # 13. Validation Must validate: * zone names * record formats * TTL ranges * forwarder endpoints * listener configs * rule syntax --- # 14. Default Bootstrap On first run: * create DB * create listeners (53 UDP/TCP) * seed forwarders (8.8.8.8, 1.1.1.1) * create empty config --- # 15. Acceptance Criteria ## DNS * resolves A/AAAA/MX/etc * works on UDP + TCP * IPv4 + IPv6 ## Auth * rules enforced * wildcard matching correct * mutations blocked without match ## API * OpenRPC fully functional * dynamic config works ## Persistence * SQLite persists everything --- # 16. Final Design Philosophy This system is: * minimal * stateless in auth * extensible * infrastructure-ready * composable with external identity systems # 17. SKILLS to be used to implement this /hero_crates_best_practices_check /hero_proc_service_selfstart /hero_sockets
Author
Owner

Implementation Spec for Issue #1 — Managed DNS Daemon

Objective

Build a minimal, production-grade DNS daemon in Rust that serves authoritative DNS queries from a SQLite-backed zone store, supports forwarding (standard DNS and peer nodes), exposes an OpenRPC management API over Unix Domain Sockets, implements stateless role-pattern authorization, and supports full runtime reconfiguration without restart.

Requirements

  • DNS Engine: UDP+TCP, IPv4+IPv6, authoritative zones, wildcard support
  • Record Types: A, AAAA, CNAME, NS, MX, TXT, SRV, PTR, SOA, CAA, NAPTR, TLSA, DNSKEY, DS, SSHFP, LOC, SPF, HINFO, RP
  • Storage: SQLite with tables for zones, records, forwarders, listeners, global_config, auth_rules
  • Forwarding: Standard DNS + peer nodes, priority + fallback, policy modes (local_only, local_then_forward, forward_only)
  • OpenRPC API: JSON-RPC 2.0 over UDS; modules: zones, records, forwarders, listeners, queries, system, health
  • Authorization: Stateless role-pattern matching, rules stored per zone with wildcard glob matching
  • Listeners: Configurable UDP+TCP on any interface/port; UDS always enabled
  • Runtime: Dynamic updates without restart, TTL-based caching, structured logging
  • Bootstrap: On first run create DB, default listeners (53 UDP/TCP), seed forwarders (8.8.8.8, 1.1.1.1)

Project Structure

my_dns/
  Cargo.toml                    # Workspace root
  Makefile
  crates/
    my_dns_sdk/                 # Shared types, protocol, client library
    my_dns_server/              # DNS daemon binary
    my_dns_cli/                 # CLI client binary
  tests/integration/            # Integration tests

Implementation Plan (11 Steps)

Step 1: Workspace Scaffold and Core Dependencies

Create Rust workspace with all crate skeletons and Cargo.toml configurations.
Dependencies: none

Step 2: SDK Domain Models, Record Types, and Validation

Define all shared types in my_dns_sdk (Zone, Record, Forwarder, Listener, AuthRule, RecordType enum, validation functions).
Dependencies: Step 1

Step 3: SDK Protocol, Socket, and Client Types

JSON-RPC 2.0 protocol types, UDS socket path resolution, async OpenRPC client.
Dependencies: Step 1

Step 4: SQLite Database Layer

Complete storage layer with schema creation, CRUD operations for all entities, and bootstrap logic.
Dependencies: Step 2

Step 5: DNS Engine — Authoritative Query Handler

Core DNS server using hickory-server that answers authoritative queries from SQLite zone store. Wildcard matching, CNAME chasing, cache.
Dependencies: Step 4

Step 6: DNS Forwarding Engine

Forwarding to upstream DNS servers and peer nodes with priority, fallback, and policy enforcement.
Dependencies: Step 5

Step 7: OpenRPC IPC Server and Method Dispatch

UDS-based JSON-RPC 2.0 server with all API method handlers for zones, records, forwarders, listeners, queries, system, health.
Dependencies: Step 4

Step 8: Authorization Layer

Stateless role-pattern authorization enforcement on all mutation RPC methods.
Dependencies: Step 7

Step 9: Bootstrap, Main Entry Point, and Runtime Lifecycle

Wire everything together in main.rs with startup sequence, signal handling, graceful shutdown.
Dependencies: Steps 5, 6, 7, 8

Step 10: CLI Client

Management CLI communicating with daemon via UDS OpenRPC.
Dependencies: Step 3

Step 11: Integration Tests and Documentation

Comprehensive integration tests covering all features.
Dependencies: Step 9, 10

Acceptance Criteria

  • Workspace compiles with cargo build --workspace --release
  • DNS queries over UDP and TCP return correct authoritative answers
  • All 19 record types can be created, queried, and deleted
  • OpenRPC API handles all CRUD operations
  • Forwarding policies enforced correctly
  • Authorization: reads public, mutations require matching role-pattern rule
  • Runtime reconfiguration without restart
  • TTL-based cache works correctly
  • Graceful shutdown on SIGTERM/SIGINT
  • CLI client manages all entities
## Implementation Spec for Issue #1 — Managed DNS Daemon ### Objective Build a minimal, production-grade DNS daemon in Rust that serves authoritative DNS queries from a SQLite-backed zone store, supports forwarding (standard DNS and peer nodes), exposes an OpenRPC management API over Unix Domain Sockets, implements stateless role-pattern authorization, and supports full runtime reconfiguration without restart. ### Requirements - DNS Engine: UDP+TCP, IPv4+IPv6, authoritative zones, wildcard support - Record Types: A, AAAA, CNAME, NS, MX, TXT, SRV, PTR, SOA, CAA, NAPTR, TLSA, DNSKEY, DS, SSHFP, LOC, SPF, HINFO, RP - Storage: SQLite with tables for zones, records, forwarders, listeners, global_config, auth_rules - Forwarding: Standard DNS + peer nodes, priority + fallback, policy modes (local_only, local_then_forward, forward_only) - OpenRPC API: JSON-RPC 2.0 over UDS; modules: zones, records, forwarders, listeners, queries, system, health - Authorization: Stateless role-pattern matching, rules stored per zone with wildcard glob matching - Listeners: Configurable UDP+TCP on any interface/port; UDS always enabled - Runtime: Dynamic updates without restart, TTL-based caching, structured logging - Bootstrap: On first run create DB, default listeners (53 UDP/TCP), seed forwarders (8.8.8.8, 1.1.1.1) ### Project Structure ``` my_dns/ Cargo.toml # Workspace root Makefile crates/ my_dns_sdk/ # Shared types, protocol, client library my_dns_server/ # DNS daemon binary my_dns_cli/ # CLI client binary tests/integration/ # Integration tests ``` ### Implementation Plan (11 Steps) #### Step 1: Workspace Scaffold and Core Dependencies Create Rust workspace with all crate skeletons and Cargo.toml configurations. Dependencies: none #### Step 2: SDK Domain Models, Record Types, and Validation Define all shared types in my_dns_sdk (Zone, Record, Forwarder, Listener, AuthRule, RecordType enum, validation functions). Dependencies: Step 1 #### Step 3: SDK Protocol, Socket, and Client Types JSON-RPC 2.0 protocol types, UDS socket path resolution, async OpenRPC client. Dependencies: Step 1 #### Step 4: SQLite Database Layer Complete storage layer with schema creation, CRUD operations for all entities, and bootstrap logic. Dependencies: Step 2 #### Step 5: DNS Engine — Authoritative Query Handler Core DNS server using hickory-server that answers authoritative queries from SQLite zone store. Wildcard matching, CNAME chasing, cache. Dependencies: Step 4 #### Step 6: DNS Forwarding Engine Forwarding to upstream DNS servers and peer nodes with priority, fallback, and policy enforcement. Dependencies: Step 5 #### Step 7: OpenRPC IPC Server and Method Dispatch UDS-based JSON-RPC 2.0 server with all API method handlers for zones, records, forwarders, listeners, queries, system, health. Dependencies: Step 4 #### Step 8: Authorization Layer Stateless role-pattern authorization enforcement on all mutation RPC methods. Dependencies: Step 7 #### Step 9: Bootstrap, Main Entry Point, and Runtime Lifecycle Wire everything together in main.rs with startup sequence, signal handling, graceful shutdown. Dependencies: Steps 5, 6, 7, 8 #### Step 10: CLI Client Management CLI communicating with daemon via UDS OpenRPC. Dependencies: Step 3 #### Step 11: Integration Tests and Documentation Comprehensive integration tests covering all features. Dependencies: Step 9, 10 ### Acceptance Criteria - [ ] Workspace compiles with `cargo build --workspace --release` - [ ] DNS queries over UDP and TCP return correct authoritative answers - [ ] All 19 record types can be created, queried, and deleted - [ ] OpenRPC API handles all CRUD operations - [ ] Forwarding policies enforced correctly - [ ] Authorization: reads public, mutations require matching role-pattern rule - [ ] Runtime reconfiguration without restart - [ ] TTL-based cache works correctly - [ ] Graceful shutdown on SIGTERM/SIGINT - [ ] CLI client manages all entities
Author
Owner

Test Results

  • Total: 148
  • Passed: 148
  • Failed: 0

Breakdown

  • my_dns_sdk: 90 tests (models, record types, validation, protocol, auth, socket)
  • my_dns_server: 58 tests (database CRUD, cache, IPC handlers)
  • my_dns_cli: 0 tests (CLI binary)

All tests pass. cargo check --workspace compiles cleanly.

## Test Results - **Total**: 148 - **Passed**: 148 - **Failed**: 0 ### Breakdown - `my_dns_sdk`: 90 tests (models, record types, validation, protocol, auth, socket) - `my_dns_server`: 58 tests (database CRUD, cache, IPC handlers) - `my_dns_cli`: 0 tests (CLI binary) All tests pass. `cargo check --workspace` compiles cleanly.
Author
Owner

Implementation Summary

Crates Created

my_dns_sdk (shared library)

  • models.rs — Domain types: Zone, Record, Forwarder, Listener, GlobalConfig with enums for ForwardPolicy, ForwarderType, ListenerProtocol
  • record_types.rs — All 19 DNS record types (A, AAAA, CNAME, NS, MX, TXT, SRV, PTR, SOA, CAA, NAPTR, TLSA, DNSKEY, DS, SSHFP, LOC, SPF, HINFO, RP)
  • validate.rs — Validation for zone names, record data, TTL, forwarder endpoints, listener configs, auth rules
  • protocol.rs — JSON-RPC 2.0 types (RpcRequest, RpcResponse, RpcError) with standard and custom error codes
  • socket.rs — UDS path resolution (env var > system > user)
  • auth.rs — Claims parsing from Bearer tokens, hierarchical dot-separated rule matching with wildcard support
  • client.rs — Async OpenRPC client over UDS
  • responses.rs — API response types
  • config.rs — Server configuration types
  • version.rs — Version info

my_dns_server (daemon binary)

  • db/ — SQLite storage layer with full CRUD for zones, records, forwarders, listeners, global_config. Bootstrap seeding on first run.
  • dns/handler.rs — Core DNS handler implementing hickory-server RequestHandler. Longest-suffix zone matching, wildcard records, CNAME chasing, cache integration.
  • dns/server.rs — DNS server wrapper binding UDP+TCP listeners
  • dns/cache.rs — TTL-based in-memory cache with DashMap
  • dns/forwarding.rs — Forward resolver with priority-based fallback using hickory-resolver
  • ipc/server.rs — UDS JSON-RPC 2.0 server with method dispatch and auth extraction
  • ipc/handlers/ — All RPC method handlers (zones, records, forwarders, listeners, queries, system, health)
  • main.rs — Entry point with clap CLI, bootstrap, IPC+DNS server startup, graceful shutdown

my_dns_cli (management CLI)

  • Full CLI with subcommands: zone, record, forwarder, listener, query, system, health
  • Auth support via --auth flag

Key Features Implemented

  • Authoritative DNS serving (UDP+TCP, IPv4+IPv6)
  • SQLite-backed zone/record storage
  • 19 DNS record types
  • Wildcard DNS records
  • Forwarding with priority/fallback and policy modes (local_only, local_then_forward, forward_only)
  • OpenRPC API over UDS with full CRUD
  • Stateless authorization with dot-separated hierarchical rule matching
  • Claims via Authorization: Bearer header (comma-separated)
  • Runtime reconfiguration
  • TTL-based caching
  • Structured JSON logging
  • Graceful shutdown on SIGTERM/SIGINT
  • Bootstrap seeding (default listeners + forwarders)

Test Results

  • 148 tests passing (90 SDK + 58 server)
  • Zero warnings
## Implementation Summary ### Crates Created **my_dns_sdk** (shared library) - `models.rs` — Domain types: Zone, Record, Forwarder, Listener, GlobalConfig with enums for ForwardPolicy, ForwarderType, ListenerProtocol - `record_types.rs` — All 19 DNS record types (A, AAAA, CNAME, NS, MX, TXT, SRV, PTR, SOA, CAA, NAPTR, TLSA, DNSKEY, DS, SSHFP, LOC, SPF, HINFO, RP) - `validate.rs` — Validation for zone names, record data, TTL, forwarder endpoints, listener configs, auth rules - `protocol.rs` — JSON-RPC 2.0 types (RpcRequest, RpcResponse, RpcError) with standard and custom error codes - `socket.rs` — UDS path resolution (env var > system > user) - `auth.rs` — Claims parsing from Bearer tokens, hierarchical dot-separated rule matching with wildcard support - `client.rs` — Async OpenRPC client over UDS - `responses.rs` — API response types - `config.rs` — Server configuration types - `version.rs` — Version info **my_dns_server** (daemon binary) - `db/` — SQLite storage layer with full CRUD for zones, records, forwarders, listeners, global_config. Bootstrap seeding on first run. - `dns/handler.rs` — Core DNS handler implementing hickory-server RequestHandler. Longest-suffix zone matching, wildcard records, CNAME chasing, cache integration. - `dns/server.rs` — DNS server wrapper binding UDP+TCP listeners - `dns/cache.rs` — TTL-based in-memory cache with DashMap - `dns/forwarding.rs` — Forward resolver with priority-based fallback using hickory-resolver - `ipc/server.rs` — UDS JSON-RPC 2.0 server with method dispatch and auth extraction - `ipc/handlers/` — All RPC method handlers (zones, records, forwarders, listeners, queries, system, health) - `main.rs` — Entry point with clap CLI, bootstrap, IPC+DNS server startup, graceful shutdown **my_dns_cli** (management CLI) - Full CLI with subcommands: zone, record, forwarder, listener, query, system, health - Auth support via --auth flag ### Key Features Implemented - Authoritative DNS serving (UDP+TCP, IPv4+IPv6) - SQLite-backed zone/record storage - 19 DNS record types - Wildcard DNS records - Forwarding with priority/fallback and policy modes (local_only, local_then_forward, forward_only) - OpenRPC API over UDS with full CRUD - Stateless authorization with dot-separated hierarchical rule matching - Claims via Authorization: Bearer header (comma-separated) - Runtime reconfiguration - TTL-based caching - Structured JSON logging - Graceful shutdown on SIGTERM/SIGINT - Bootstrap seeding (default listeners + forwarders) ### Test Results - 148 tests passing (90 SDK + 58 server) - Zero warnings
Author
Owner

Implementation committed: 93fcd15

Browse: 93fcd15

Implementation committed: `93fcd15` Browse: https://forge.ourworld.tf/geomind_code/my_dns/commit/93fcd15
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
geomind_code/my_dns#1
No description provided.