Your server answers hardcoded A records. This module's material — binary protocols, UDP, concurrency at the socket level — finishes it.
Milestone 4 — Real zone, real answers
- Zone file loader: parse the
zones.confformat from the project page intomap[string][]Recordat startup. - NXDOMAIN: RCODE 3 for domains not in the zone.
- All five record types: A, AAAA, CNAME, MX, TXT — each has its RDATA format in the project page's table.
- Name compression: handle pointer bytes (
0xC0 ...) when decoding, use0xC00Cwhen encoding answers.
Done when every dig example in the project page's Usage section returns the right records, and dig nope.local returns status NXDOMAIN.
Milestone 5 — Concurrent + forwarding
One goroutine per query. Prove it holds up:
for i in $(seq 50); do dig @localhost -p 5353 web.local A & done; waitFifty clean answers, and
go test -race ./...stays green.Upstream forwarding:
--upstream 8.8.8.8:53relays unknown domains and returns the upstream answer.README with a real dig session transcript. Push it.
Shipped: three of five. "I built a DNS server in Go from scratch" — that sentence is now true, and you have the repo to prove it.