dns

DNS client and server implementations using the Go project's dnsmessage package
Log | Files | Refs | README | LICENSE

commit 1bcf9fa40865b1840d67029d990dcbfe61a43a23
parent 0500699332efdcf7796b1879af478f78f096d221
Author: Oliver Lowe <o@olowe.co>
Date:   Tue, 16 Nov 2021 09:48:37 +1100

Move core DNS routines into the dns package

because it doesn't really have anything to do with DNS over HTTPS

Diffstat:
Mcmd/dohproxy/dohproxy.go | 41+++++++----------------------------------
Mdns.go | 37+++++++++++++++++++++++++++++++++++++
2 files changed, 44 insertions(+), 34 deletions(-)

diff --git a/cmd/dohproxy/dohproxy.go b/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.Request) { 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.Request) { 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) diff --git a/dns.go b/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 +}