Commit Diff


commit - 9f874ebabf29b3b405b3dc9f372a3817316c0ce7
commit + ad190d6323ad7247346e80062588e43990bb8a8f
blob - 3a385eebd1b1065e285efd3cdca63f4595250131
blob + d3b31b682c98a6aabc29053f53a6565ad6213b71
--- dns.go
+++ dns.go
@@ -16,7 +16,7 @@ DNS server, then handling the reply using Exchange:
 			// ...
 		},
 	}
-	rmsg, err := Exchange(qmsg, "9.9.9.9:domain")
+	rmsg, err := dns.Exchange(qmsg, "9.9.9.9:domain")
 	// ...
 
 Queries to a recursive resolver via DNS over TLS (DoT) can be made with ExchangeTLS:
@@ -35,8 +35,35 @@ Queries to a recursive resolver via DNS over TLS (DoT)
 			},
 		},
 	}
-	rmsg, err := ExchangeTLS(qmsg, "9.9.9.9:853")
+	rmsg, err := dns.ExchangeTLS(qmsg, "9.9.9.9:853")
 
+ListenAndServe starts a DNS server listening on the given network and
+address. Received messages are managed with the given Handler in a new
+goroutine. Handler may be nil, in which case all messages are
+gracefully refused.
+
+	log.Fatal(dns.ListenAndServe("udp", ":domain", nil))
+
+Handlers are just functions to which a DNS message from the server is
+passed. Responses are written to ResponseWriter.
+
+	func myHandler(w dns.ResponseWriter, qmsg *dnsmessage.Message) {
+		var rmsg dnsmessage.Message
+		rmsg.Header.ID = qmsg.Header.ID
+		if rmsg.Header.RecursionDesired {
+			rmsg.Header.RCode = dnsmessage.RCodeRefused
+			w.WriteMsg(rmsg)
+			return
+		}
+		// answer questions...
+	}
+
+A Server may be created with a custom net.Listener:
+
+	l, err := tls.Listen(network, addr, config)
+	srv := &dns.Server{Handler: myHandler}
+	log.Fatal(srv.Serve(l))
+
 */
 package dns
 
blob - a6c1e176b6a32bf2f33f125c0d9df92e9c967d70
blob + eb8b74b731f3c0d006bad61bec481f4699bf6d24
--- server.go
+++ server.go
@@ -5,7 +5,8 @@ import (
 	"net"
 )
 
-// Server contains settings for running a DNS server.
+// Server contains settings for running a DNS server. An empty Server
+// with a nil Handler is a valid configuration.
 type Server struct {
 	network string
 	addr    string