diff --git a/TODO b/TODO index 59217308..3d551e35 100644 --- a/TODO +++ b/TODO @@ -5,6 +5,7 @@ Todo: * Parsing from strings, going with goyacc and own lexer * NSEC and nsec3 closest encloser helper functions * TKEY +* Large TXT records Issues: * Check the network order, it works now, but this is on Intel?? diff --git a/_examples/axfr/axfr.go b/_examples/axfr/axfr.go index 6a3aff8a..b7fd0f83 100644 --- a/_examples/axfr/axfr.go +++ b/_examples/axfr/axfr.go @@ -9,31 +9,38 @@ import ( func main() { var serial *int = flag.Int("serial", 0, "Perform an IXFR with the given serial") + var onesoa *bool = flag.Bool("1soa", false, "Don't print the last SOA") flag.Parse() res := new(dns.Resolver) res.FromFile("/etc/resolv.conf") - res.Servers[0] = "213.154.224.1" ch := make(chan dns.RR) m := new(dns.Msg) m.Question = make([]dns.Question, 1) if *serial > 0 { - m.Question[0] = dns.Question{"tjeb.nl.", dns.TypeIXFR, dns.ClassINET} + m.Question[0] = dns.Question{"miek.nl.", dns.TypeIXFR, dns.ClassINET} soa := new(dns.RR_SOA) - soa.Hdr = dns.RR_Header{"tjeb.nl.", dns.TypeSOA, dns.ClassINET, 14400, 0} + soa.Hdr = dns.RR_Header{"miek.nl.", dns.TypeSOA, dns.ClassINET, 14400, 0} soa.Serial = uint32(*serial) m.Ns = make([]dns.RR, 1) m.Ns[0] = soa go res.Ixfr(m, ch) } else { - m.Question[0] = dns.Question{"tjeb.nl.", dns.TypeAXFR, dns.ClassINET} + m.Question[0] = dns.Question{"miek.nl.", dns.TypeAXFR, dns.ClassINET} go res.Axfr(m, ch) } + soa := false for x := range ch { + if x.Header().Rrtype == dns.TypeSOA { + if *onesoa && soa { + continue + } + soa = true + } fmt.Printf("%v\n",x) } } diff --git a/resolver.go b/resolver.go index 5ebc0ece..2d38df9e 100644 --- a/resolver.go +++ b/resolver.go @@ -136,7 +136,7 @@ Server: continue Server } state := FIRST - var serial int // The first serial seen is the current server serial + var serial uint32 // The first serial seen is the current server serial var _ = serial defer c.Close() @@ -161,30 +161,37 @@ Server: if state == FIRST { // A single SOA RR signals "no changes" - if len(in.Answer) == 1 && checkSOA(in, true) { + if len(in.Answer) == 1 && checkAxfrSOA(in, true) { c.Close() return } // But still check if the returned answer is ok - if !checkSOA(in, true) { + if !checkAxfrSOA(in, true) { c.Close() continue Server } // This serial is important - serial = int(in.Answer[0].(*RR_SOA).Serial) + serial = in.Answer[0].(*RR_SOA).Serial sendFromMsg(in, m) state = SECOND } // Now we need to check each message for SOA records, to see what we need to do if state != FIRST { - if !checkSOA(in, false) { + // If the last record in the IXFR contains the servers' SOA + // we should quit + +// for _, r := range in.Answer { + + +// } + + if !checkAxfrSOA(in, false) { // Soa record not the last one sendFromMsg(in, m) continue } else{ - c.Close() sendFromMsg(in, m) return } @@ -252,7 +259,7 @@ Server: } if first { - if !checkSOA(in, true) { + if !checkAxfrSOA(in, true) { c.Close() continue Server } @@ -261,12 +268,11 @@ Server: } if !first { - if !checkSOA(in, false) { + if !checkAxfrSOA(in, false) { // Soa record not the last one sendFromMsg(in, m) continue } else { - c.Close() sendFromMsg(in, m) return } @@ -439,7 +445,7 @@ func recvTCP(c net.Conn) ([]byte, os.Error) { // Check if he SOA record exists in the Answer section of // the packet. If first is true the first RR must be a soa // if false, the last one should be a SOA -func checkSOA(in *Msg, first bool) bool { +func checkAxfrSOA(in *Msg, first bool) bool { if len(in.Answer) > 0 { if first { return in.Answer[0].Header().Rrtype == TypeSOA @@ -450,6 +456,21 @@ func checkSOA(in *Msg, first bool) bool { return false } +// Same as Axfr one, but now also check the serial +func checkIxfrSOA(in *Msg, first bool, serial uint32) bool { + if len(in.Answer) > 0 { + if first { + return in.Answer[0].Header().Rrtype == TypeSOA && + in.Answer[0].(*RR_SOA).Serial == serial + } else { + return in.Answer[len(in.Answer)-1].Header().Rrtype == TypeSOA && + in.Answer[len(in.Answer)-1].(*RR_SOA).Serial == serial + } + } + return false +} + + // Send the answer section to the channel func sendFromMsg(in *Msg, c chan RR) { for _, r := range in.Answer {