Skip to content

Instantly share code, notes, and snippets.

@armon
Created January 3, 2014 23:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save armon/8248769 to your computer and use it in GitHub Desktop.
Save armon/8248769 to your computer and use it in GitHub Desktop.
package main
import (
"github.com/miekg/dns"
"log"
"net"
"time"
)
const (
recursor = "8.8.8.8:53" // Google DNS
)
func main() {
mux := dns.NewServeMux()
udp := &dns.Server{
Addr: "127.0.0.1:8600",
Net: "udp",
Handler: mux,
UDPSize: 65535,
}
tcp := &dns.Server{
Addr: "127.0.0.1:8600",
Net: "tcp",
Handler: mux,
}
mux.HandleFunc(".", handleRecurse)
go udp.ListenAndServe()
go tcp.ListenAndServe()
select {}
}
func handleRecurse(resp dns.ResponseWriter, req *dns.Msg) {
q := req.Question[0]
network := "udp"
defer func(s time.Time) {
log.Printf("[DEBUG] dns: request for %v (%s) (%v)", q, network, time.Now().Sub(s))
}(time.Now())
// Switch to TCP if the client is
if _, ok := resp.RemoteAddr().(*net.TCPAddr); ok {
network = "tcp"
}
// Recursively resolve
c := &dns.Client{Net: network}
r, rtt, err := c.Exchange(req, recursor)
// On failure, return a SERVFAIL message
if err != nil {
log.Printf("[ERR] dns: recurse failed: %v", err)
m := &dns.Msg{}
m.SetReply(req)
m.SetRcode(req, dns.RcodeServerFailure)
resp.WriteMsg(m)
return
}
log.Printf("[DEBUG] dns: recurse RTT for %v (%v)", q, rtt)
// TOGGLE COMPRESS TO BREAK RESPONSE
r.Compress = true
// Forward the response
if err := resp.WriteMsg(r); err != nil {
log.Printf("[WARN] dns: failed to respond: %v", err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment