Fix outing TSIG on axfr
This commit is contained in:
parent
ef4d85fa6d
commit
76daa7f08b
|
@ -1,64 +1,72 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os"
|
||||
"dns"
|
||||
"fmt"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func handleXfr(d *dns.Conn, i *dns.Msg) {
|
||||
if i.IsAxfr() {
|
||||
fmt.Printf("Axfr request seen\n")
|
||||
if i.Question[0].Name == Zone.name {
|
||||
fmt.Printf("Matching current zone\n")
|
||||
m := make(chan *dns.Xfr)
|
||||
go d.XfrWrite(i, m)
|
||||
for j := 0; j < Zone.size; j++ {
|
||||
m <- &dns.Xfr{Add: true, RR: Zone.rrs[j]}
|
||||
}
|
||||
close(m)
|
||||
}
|
||||
}
|
||||
func handleXfr(d *dns.Conn, i *dns.Msg) os.Error {
|
||||
if i.IsAxfr() {
|
||||
fmt.Printf("Axfr request seen\n")
|
||||
if i.Question[0].Name == Zone.name {
|
||||
fmt.Printf("Matching current zone\n")
|
||||
m := make(chan *dns.Xfr)
|
||||
e := make(chan os.Error)
|
||||
defer close(m)
|
||||
defer close(e)
|
||||
go d.XfrWrite(i, m, e)
|
||||
for j := 0; j < Zone.size; j++ {
|
||||
select {
|
||||
case m <- &dns.Xfr{Add: true, RR: Zone.rrs[j]}: //
|
||||
case err := <-e:
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func handleNotify(d *dns.Conn, i *dns.Msg) {
|
||||
if i.IsNotify() {
|
||||
fmt.Printf("Notify seen\n")
|
||||
q := new(dns.Msg)
|
||||
q.SetReply(i)
|
||||
err := d.WriteMsg(q)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
doXfrIn(i)
|
||||
}
|
||||
func handleNotify(d *dns.Conn, i *dns.Msg) os.Error {
|
||||
if i.IsNotify() {
|
||||
fmt.Printf("Notify seen\n")
|
||||
q := new(dns.Msg)
|
||||
q.SetReply(i)
|
||||
err := d.WriteMsg(q)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
doXfrIn(i)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func doXfrIn(i *dns.Msg) ([]dns.RR, os.Error) {
|
||||
q := new(dns.Msg)
|
||||
q.SetAxfr(i.Question[0].Name)
|
||||
q := new(dns.Msg)
|
||||
q.SetAxfr(i.Question[0].Name)
|
||||
|
||||
m := make(chan *dns.Xfr)
|
||||
fmt.Printf("Preparing Xfr for %s\n", i.Question[0].Name)
|
||||
m := make(chan *dns.Xfr)
|
||||
fmt.Printf("Preparing Xfr for %s\n", i.Question[0].Name)
|
||||
|
||||
d := new(dns.Conn)
|
||||
d.RemoteAddr = "127.0.0.1:53"
|
||||
err := d.Dial("tcp")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer d.Close()
|
||||
d := new(dns.Conn)
|
||||
d.RemoteAddr = "127.0.0.1:53"
|
||||
err := d.Dial("tcp")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer d.Close()
|
||||
|
||||
fmt.Printf("Calling 127.0.0.1 successful\n")
|
||||
go d.XfrRead(q, m)
|
||||
fmt.Printf("Calling 127.0.0.1 successful\n")
|
||||
go d.XfrRead(q, m)
|
||||
|
||||
Zone.name = i.Question[0].Name
|
||||
j := 0
|
||||
for x := range m {
|
||||
fmt.Printf("%v %v\n", x.Add, x.RR)
|
||||
Zone.rrs[j] = x.RR
|
||||
j++
|
||||
}
|
||||
Zone.size = j
|
||||
return nil, nil
|
||||
Zone.name = i.Question[0].Name
|
||||
j := 0
|
||||
for x := range m {
|
||||
fmt.Printf("%v %v\n", x.Add, x.RR)
|
||||
Zone.rrs[j] = x.RR
|
||||
j++
|
||||
}
|
||||
Zone.size = j
|
||||
return nil, nil
|
||||
}
|
||||
|
|
30
xfr.go
30
xfr.go
|
@ -16,6 +16,7 @@ type Xfr struct {
|
|||
// be considered to have faild.
|
||||
Err os.Error
|
||||
}
|
||||
// todo maybe add the SOA serial too?
|
||||
|
||||
// Perform an incoming Ixfr or Axfr. If the message q's question
|
||||
// section contains an AXFR type an Axfr is performed. If q's question
|
||||
|
@ -50,15 +51,16 @@ func (d *Conn) XfrRead(q *Msg, m chan *Xfr) {
|
|||
// Perform an outgoing Ixfr or Axfr. If the message q's question
|
||||
// section contains an AXFR type an Axfr is performed. If q's question
|
||||
// section contains an IXFR type an Ixfr is performed.
|
||||
// The message q is written to the connection in d.
|
||||
func (d *Conn) XfrWrite(q *Msg, m chan *Xfr) {
|
||||
// The actual records to send are given on the channel m. And errors
|
||||
// during transport are return on channel e.
|
||||
func (d *Conn) XfrWrite(q *Msg, m chan *Xfr, e chan os.Error) {
|
||||
switch q.Question[0].Qtype {
|
||||
case TypeAXFR:
|
||||
d.axfrWrite(q, m)
|
||||
d.axfrWrite(q, m, e)
|
||||
case TypeIXFR:
|
||||
// d.ixfrWrite(q, m)
|
||||
default:
|
||||
m <- &Xfr{true, nil, &Error{Error: "Xfr Qtype not recognized"}}
|
||||
e <- &Xfr{true, nil, &Error{Error: "Xfr Qtype not recognized"}}
|
||||
close(m)
|
||||
}
|
||||
}
|
||||
|
@ -105,20 +107,22 @@ func (d *Conn) axfrRead(q *Msg, m chan *Xfr) {
|
|||
}
|
||||
|
||||
// Just send the zone
|
||||
func (d *Conn) axfrWrite(q *Msg, m chan *Xfr) {
|
||||
func (d *Conn) axfrWrite(q *Msg, m chan *Xfr, e chan os.Error) {
|
||||
out := new(Msg)
|
||||
out.Id = q.Id
|
||||
out.Question = q.Question
|
||||
out.Answer = make([]RR, 1001)
|
||||
out.Answer = make([]RR, 1001) // TODO(mg) look at this number
|
||||
out.MsgHdr.Response = true
|
||||
out.MsgHdr.Authoritative = true
|
||||
first := true
|
||||
var soa *RR_SOA
|
||||
i := 0
|
||||
for r := range m {
|
||||
out.Answer[i] = r.RR
|
||||
if soa == nil {
|
||||
if r.RR.Header().Rrtype != TypeSOA {
|
||||
/* ... */
|
||||
e <- ErrXfrSoa
|
||||
return
|
||||
} else {
|
||||
soa = r.RR.(*RR_SOA)
|
||||
}
|
||||
|
@ -128,20 +132,26 @@ func (d *Conn) axfrWrite(q *Msg, m chan *Xfr) {
|
|||
// Send it
|
||||
err := d.WriteMsg(out)
|
||||
if err != nil {
|
||||
/* ... */
|
||||
e <- err
|
||||
return
|
||||
}
|
||||
i = 0
|
||||
// Gaat dit goed?
|
||||
out.Answer = out.Answer[:0]
|
||||
if first {
|
||||
if d.Tsig != nil {
|
||||
d.Tsig.TimersOnly = true
|
||||
}
|
||||
first = !first
|
||||
}
|
||||
}
|
||||
// TimersOnly foo for TSIG
|
||||
}
|
||||
// Everything is sent, only the closing soa is left.
|
||||
out.Answer[i] = soa
|
||||
out.Answer = out.Answer[:i+1]
|
||||
err := d.WriteMsg(out)
|
||||
if err != nil {
|
||||
println(err.String())
|
||||
e <- err
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue