commit - 0be319b95e9008dcc63694c16025f23e90e74300
commit + ded9109ce8770cd39b01c1fb5a8afdc1bd1fc335
blob - d278a355c3d7d6eb09a0cb152f43504fc9f50f13
blob + 4b1c81b5517c84971733bfca0c64fb78887e973e
--- cmd/recursor/recursor.go
+++ cmd/recursor/recursor.go
"net"
"strings"
"sync"
- "time"
- "math/rand"
"golang.org/x/net/dns/dnsmessage"
"olowe.co/dns"
)
return net.JoinHostPort(ip.String(), "domain")
}
-func newID() uint16 {
- return uint16(rand.Intn(65535))
-}
-
func nextServerAddrs(resources []dnsmessage.Resource) []net.IP {
var next []net.IP
for _, r := range resources {
}
func resolve(q dnsmessage.Question, next []net.IP) (dnsmessage.Message, error) {
- qmsg := dnsmessage.Message{
- Header: dnsmessage.Header{ID: newID()},
- Questions: []dnsmessage.Question{q},
- }
var rmsg dnsmessage.Message
var err error
for _, ip := range next {
continue
}
fmt.Fprintf(os.Stderr, "asking %s about %s\n", ip, q.Name)
- rmsg, err = dns.Exchange(qmsg, ip2dial(ip))
+ rmsg, err = dns.Ask(q, ip2dial(ip))
if rmsg.Header.Authoritative {
return rmsg, err
} else if rmsg.Header.RCode == dnsmessage.RCodeSuccess && err == nil {
fmt.Fprintf(os.Stderr, "cache served %s %s\n", q.Name, q.Type)
return
}
- cache.RUnlock()
+ cache.RUnlock()
resolved, err := resolveFromRoot(q)
if err != nil {
}{m: make(map[dnsmessage.Question][]dnsmessage.Resource)}
func main() {
- rand.Seed(time.Now().UnixNano())
fmt.Fprintln(os.Stderr, dns.ListenAndServe("udp", "", handler))
}
blob - 40080dee87ebf41f36afab6100cf11604559119f
blob + 42e892fbcf995c094bec224548ebda83d2efd8a8
--- dns.go
+++ dns.go
"errors"
"fmt"
"io"
+ "math/rand"
"net"
+ "time"
"golang.org/x/net/dns/dnsmessage"
)
var errMismatchedID = errors.New("mismatched message id")
+var randomsrc *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano()))
+
+func newID() uint16 {
+ return uint16(randomsrc.Intn(65535))
+}
+
+// Ask sends a message with q to addr and returns its response.
+// The exchange is unencrypted using UDP.
+func Ask(q dnsmessage.Question, addr string) (dnsmessage.Message, error) {
+ qmsg := dnsmessage.Message{
+ Header: dnsmessage.Header{ID: newID()},
+ Questions: []dnsmessage.Question{q},
+ }
+ return Exchange(qmsg, addr)
+}
+
+// Ask sends a message with q to addr and returns its response.
+// The exchange is unencrypted using TCP.
+func AskTCP(q dnsmessage.Question, addr string) (dnsmessage.Message, error) {
+ qmsg := dnsmessage.Message{
+ Header: dnsmessage.Header{ID: newID()},
+ Questions: []dnsmessage.Question{q},
+ }
+ return ExchangeTCP(qmsg, addr)
+}
+
+// Ask sends a message with q to addr and returns its response.
+// The exchange is encrypted using DNS over TLS.
+func AskTLS(q dnsmessage.Question, addr string) (dnsmessage.Message, error) {
+ qmsg := dnsmessage.Message{
+ Header: dnsmessage.Header{ID: newID()},
+ Questions: []dnsmessage.Question{q},
+ }
+ return ExchangeTLS(qmsg, addr)
+}
+
// 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) {
blob - 40e6d3d9fe3e29f4aa1a11c04f9868ba925b4a7f
blob + 6d63e59a3f88930b69912f9553f3149377ed7bcc
--- server_test.go
+++ server_test.go
package dns
import (
+ "golang.org/x/net/dns/dnsmessage"
"testing"
)
go func() {
t.Fatal(ListenAndServe("udp", "127.0.0.1:51111", nil))
}()
- q, err := buildmsg("www.example.com.")
+ q := dnsmessage.Question{Name: dnsmessage.MustNewName("www.example.com."), Type: dnsmessage.TypeA, Class: dnsmessage.ClassINET}
+ rmsg, err := Ask(q, "127.0.0.1:51111")
if err != nil {
- t.Fatalf("create query: %v", err)
- }
- rmsg, err := Exchange(q, "127.0.0.1:51111")
- if err != nil {
t.Errorf("exchange: %v", err)
}
t.Log("response:", rmsg)
go func() {
t.Fatal(ListenAndServe("tcp", "127.0.0.1:51112", nil))
}()
- q, err := buildmsg("www.example.com.")
+ q := dnsmessage.Question{Name: dnsmessage.MustNewName("www.example.com."), Type: dnsmessage.TypeA, Class: dnsmessage.ClassINET}
+ rmsg, err := AskTCP(q, "127.0.0.1:51112")
if err != nil {
- t.Fatal("create query:", err)
- }
- rmsg, err := ExchangeTCP(q, "127.0.0.1:51112")
- if err != nil {
t.Errorf("exchange: %v", err)
}
t.Log("response:", rmsg)
t.Fatal(srv.ListenAndServe())
t.Log(srv.addr)
}()
- q, err := buildmsg("www.example.com.")
+ q := dnsmessage.Question{Name: dnsmessage.MustNewName("www.example.com."), Type: dnsmessage.TypeA, Class: dnsmessage.ClassINET}
+ rmsg, err := Ask(q, "127.0.0.1:domain")
if err != nil {
- t.Fatal("create query:", err)
- }
- rmsg, err := Exchange(q, "127.0.0.1:domain")
- if err != nil {
t.Errorf("exchange: %v", err)
}
t.Log("response:", rmsg)