diff --git a/TODO b/TODO index 07b5d254..8cc29a16 100644 --- a/TODO +++ b/TODO @@ -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 diff --git a/_examples/mx/mx.go b/_examples/mx/mx.go index cd289488..8e5e9c2d 100644 --- a/_examples/mx/mx.go +++ b/_examples/mx/mx.go @@ -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]) diff --git a/_examples/q/q.go b/_examples/q/q.go index 41a6e332..bde70fd9 100644 --- a/_examples/q/q.go +++ b/_examples/q/q.go @@ -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 diff --git a/dns.go b/dns.go index 704df8da..44540102 100644 --- a/dns.go +++ b/dns.go @@ -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) } diff --git a/msg.go b/msg.go index 3f7c2881..07e5d88b 100644 --- a/msg.go +++ b/msg.go @@ -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). diff --git a/resolver.go b/resolver.go index 52d31643..5ea0ee27 100644 --- a/resolver.go +++ b/resolver.go @@ -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