Add QuerySimple

Some examples are working again. Things are getting
better.

Still need to think about a generic Config (ClientConfig)
for parsing the /etc/resolv.conf
This commit is contained in:
Miek Gieben 2011-03-29 10:15:42 +02:00
parent 5130184443
commit 2d7a1cddeb
6 changed files with 48 additions and 23 deletions

8
TODO
View File

@ -1,15 +1,11 @@
Guidelines for the API:
o symmetrical, client side should be mirrored in the server
o clean, small API
o fast data structures (rb-tree, when they come available)
o api-use should be self documenting
o zone structure -- only as rb-tree
o fast data structures (rb-tree, when they come available)
o build simple: just query function, built on the cool stuff
o make questions fqdns -- add last dot
o zone structure -- only as rb-tree or other radix tree
o compression (only ownernames?)
o Key2DS, also for offline keys -- need to parse them ofcourse
o Tsig will probably become an interface which has all configuration
@ -25,6 +21,8 @@ Issues:
* Check the network order, it works now, but this is on Intel??
* Make the testsuite work with public DNS servers
* pack/Unpack smaller. EDNS 'n stuff can be folded in
* Config from /etc/resolv.conf
* d.Dial() and redialing those that work
Examples:
* Test impl of nameserver, with a small zone, 1 KSK and online signing

View File

@ -9,18 +9,27 @@ import (
)
func main() {
r := new(dns.Resolver)
r.FromFile("/etc/resolv.conf") // Need to fix this a bit...
if len(os.Args) != 2 {
fmt.Printf("%s DOMAIN\n", os.Args[0])
os.Exit(1)
}
d := new(dns.Conn)
ser, err := dns.FromFile("/etc/resolv.conf")
d.RemoteAddr = ser[0]
m := new(dns.Msg)
m.MsgHdr.RecursionDesired = true //only set this bit
m.Id = dns.Id()
m.MsgHdr.RecursionDesired = true
m.Question = make([]dns.Question, 1)
m.Question[0] = dns.Question{os.Args[1], dns.TypeMX, dns.ClassINET}
in, err := r.Query(m)
err = d.Dial("udp")
if err != nil {
fmt.Printf("*** error: %s\n", err.String())
os.Exit(1)
}
in, err := dns.QuerySimple(d, m)
if in != nil {
if in.Rcode != dns.RcodeSuccess {
fmt.Printf(" *** invalid answer name %s after MX query for %s\n", os.Args[1], os.Args[1])

View File

@ -24,7 +24,9 @@ func main() {
flag.PrintDefaults()
}
nameserver := "@127.0.0.1" // Default nameserver
// Need to think about it... Config
server, _ := dns.FromFile("/etc/resolv.conf")
nameserver := "@" + server[0]
qtype := uint16(dns.TypeA) // Default qtype
qclass := uint16(dns.ClassINET) // Default qclass
var qname []string

35
dns.go
View File

@ -16,21 +16,34 @@
// The package dns supports querying, incoming/outgoing Axfr/Ixfr, TSIG, EDNS0,
// dynamic updates, notifies and DNSSEC validation/signing.
//
// A lot of functions take a dns message. Use pattern for creating one:
//
// message := new(Msg)
//
// // Create message with the desired options.
// message.MsgHdr.Recursion_desired = true
//
// // Create room in for the question and set it.
// message.Question = make([]Question, 1)
// message.Question[0] = Question{"miek.nl", TypeSOA, ClassINET}
//
// Basic use pattern for synchronize querying of the DNS:
//
// dnsconn := new(Conn)
// dnsconn.RemoteAddr = "127.0.0.1:53"
// dnsconn.Dial("udp") // "tcp" for tcp connection
// in, err := SimpleQuery(dnsconn, message)
//
// (Asynchronize) querying the DNS is done by using the Conn structure.
// Basic use pattern for creating such a resolver:
//
// in := make(chan Query)
// out := QueryAndServeUDP(in, nil) // nil means use QueryDefault()
// d := new(Conn)
// d.RemoteAddr = "8.8.8.8:53"
// out := QueryAndServeUDP(in, nil) // nil means use QueryDefault()
// dnsconn := new(Conn)
// dnsconn.RemoteAddr = "8.8.8.8:53"
//
// // Create message with the desired options.
// m.MsgHdr.Recursion_desired = true
// m.Question = make([]Question, 1)
// m.Question[0] = Question{"miek.nl", TypeSOA, ClassINET}
//
// in <- Query{Msg: m, Conn: d} // Send query using the above message
// reply := <-out // Listen for the reply
// in <- Query{Msg: message, Conn: dnscon}
// reply := <-out
//
// Server side programming is also supported also by using a Conn structure.
// Basic use pattern for creating an UDP DNS server:
@ -298,7 +311,7 @@ func (d *Conn) Write(p []byte) (n int, err os.Error) {
} else {
attempts = d.Attempts
}
// Mangle before TSIG?
if d.Mangle != nil {
p = d.Mangle(p)
}

3
msg.go
View File

@ -33,6 +33,7 @@ var (
ErrId os.Error = &Error{Error: "id mismatch"}
ErrShortRead os.Error = &Error{Error: "short read"}
ErrConn os.Error = &Error{Error: "conn holds both UDP and TCP connection"}
ErrConnEmpy os.Error = &Error{Error: "conn has no connection"}
ErrServ os.Error = &Error{Error: "no servers could be reached"}
ErrKey os.Error = &Error{Error: "bad key"}
ErrPrivKey os.Error = &Error{Error: "bad private key"}
@ -44,7 +45,7 @@ var (
ErrSigGen os.Error = &Error{Error: "bad signature generation"}
ErrAuth os.Error = &Error{Error: "bad authentication"}
ErrXfrSoa os.Error = &Error{Error: "no SOA seen"}
ErrHandle os.Error = &Error{Error: "the handle is nill"}
ErrHandle os.Error = &Error{Error: "handle is nill"}
)
// A manually-unpacked version of (id, bits).

View File

@ -44,7 +44,7 @@ func query(n string, in, out chan Query, f func(*Conn, *Msg, chan Query)) {
for {
select {
case q := <-in:
c, err := net.Dial(n, "", q.Conn.RemoteAddr)
c, err := net.Dial(n, q.Conn.LocalAddr, q.Conn.RemoteAddr)
if err != nil {
out <- Query{Err: err}
}
@ -87,6 +87,8 @@ func QuerySimple(d *Conn, m *Msg) (*Msg, os.Error) {
if !ok {
return nil, ErrPack
}
// Dialing should happen in the client
ret, err := d.Exchange(buf, false)
if err != nil {
return nil, err