commit 1bcf9fa40865b1840d67029d990dcbfe61a43a23 from: Oliver Lowe date: Mon Nov 15 22:48:37 2021 UTC Move core DNS routines into the dns package because it doesn't really have anything to do with DNS over HTTPS commit - 0500699332efdcf7796b1879af478f78f096d221 commit + 1bcf9fa40865b1840d67029d990dcbfe61a43a23 blob - 9f9e7c4fce25cec9470d84094173f1178fd40728 blob + 47ba0dc39d58efbdec7c563c02c362ae15bd4a4a --- cmd/dohproxy/dohproxy.go +++ cmd/dohproxy/dohproxy.go @@ -1,48 +1,21 @@ package main import ( - "net" + "fmt" + "golang.org/x/crypto/acme/autocert" + "golang.org/x/net/dns/dnsmessage" "io" - "net/http" "log" - "fmt" + "net/http" "strconv" + "git.sr.ht/~otl/dns" - "golang.org/x/crypto/acme/autocert" - "golang.org/x/net/dns/dnsmessage" ) // https://quad9.net const quad9 string = "9.9.9.9:domain" const cloudflare string = "1.1.1.1:domain" -func forward(msg dnsmessage.Message) (dnsmessage.Message, error) { - packed, err := msg.Pack() - if err != nil { - return dnsmessage.Message{}, err - } - - conn, err := net.Dial("udp", quad9) - if err != nil { - return dnsmessage.Message{}, err - } - defer conn.Close() - if _, err := conn.Write(packed); err != nil { - return dnsmessage.Message{}, err - } - buf := make([]byte, 1024) - n, err := conn.Read(buf) - if err != nil { - return dnsmessage.Message{}, err - } - - var rmsg dnsmessage.Message - if err := rmsg.Unpack(buf[:n]); err != nil { - return dnsmessage.Message{}, err - } - return rmsg, nil -} - func dnsHandler(w http.ResponseWriter, req *http.Request) { if v, ok := req.Header["Content-Type"]; ok { for _, s := range v { @@ -50,7 +23,7 @@ func dnsHandler(w http.ResponseWriter, req *http.Reque err := fmt.Errorf("unsupported media type %s", s) log.Println(err.Error()) http.Error(w, err.Error(), http.StatusUnsupportedMediaType) - return + return } } } @@ -101,7 +74,7 @@ func dnsHandler(w http.ResponseWriter, req *http.Reque http.Error(w, "unpack query: "+err.Error(), http.StatusInternalServerError) } - resolved, err := forward(msg) + resolved, err := dns.Exchange(msg, quad9) if err != nil { log.Println(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) blob - 9fccf8580adac92df56a618dc946d7db40322e52 blob + 0c66051917400b8253ab00299af5f82fa2c73de1 --- dns.go +++ dns.go @@ -1,5 +1,42 @@ package dns +import ( + "net" + + "golang.org/x/net/dns/dnsmessage" +) + // https://datatracker.ietf.org/doc/html/rfc8484 const MediaType string = "application/dns-message" const MaxMsgSize int = 65535 // max size of a message in bytes + +// Exchange performs a synchronous, unencrypted UDP DNS exchange with addr and returns its +// reply to msg. +func Exchange(msg dnsmessage.Message, addr string) (dnsmessage.Message, error) { + conn, err := net.Dial("udp", addr) + if err != nil { + return dnsmessage.Message{}, err + } + defer conn.Close() + return send(msg, conn) +} + +func send(msg dnsmessage.Message, conn net.Conn) (dnsmessage.Message, error) { + packed, err := msg.Pack() + if err != nil { + return dnsmessage.Message{}, err + } + if _, err := conn.Write(packed); err != nil { + return dnsmessage.Message{}, err + } + buf := make([]byte, 1024) + n, err := conn.Read(buf) + if err != nil { + return dnsmessage.Message{}, err + } + var rmsg dnsmessage.Message + if err := rmsg.Unpack(buf[:n]); err != nil { + return dnsmessage.Message{}, err + } + return rmsg, nil +}