Create xfr proxy

This commit is contained in:
Miek Gieben 2011-03-23 10:48:21 +01:00
parent 8b70e31c41
commit 8b2882673f
4 changed files with 66 additions and 14 deletions

View File

@ -7,21 +7,39 @@ import (
"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)
var x dns.Xfr
go d.XfrWrite(i, m)
for j := 0; j < Zone.size; j++ {
x.Add = true
x.RR = Zone.rrs[j]
m <- x
}
close(m)
}
}
}
func handleNotify(d *dns.Conn, i *dns.Msg) {
if i.IsNotify() {
fmt.Printf("Notify seen\n")
q := new(dns.Msg)
q.SetReply(i)
answer, ok := q.Pack()
if !ok {
err := d.WriteMsg(q)
if err != nil {
return
}
d.Write(answer)
doXfr(i)
doXfrIn(i)
}
}
func doXfr(i *dns.Msg) ([]dns.RR, os.Error) {
func doXfrIn(i *dns.Msg) ([]dns.RR, os.Error) {
q := new(dns.Msg)
q.SetAxfr(i.Question[0].Name)
@ -38,8 +56,13 @@ func doXfr(i *dns.Msg) ([]dns.RR, os.Error) {
d.TCP = c.(*net.TCPConn)
d.Addr = d.TCP.RemoteAddr()
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
}

View File

@ -16,11 +16,21 @@ import (
"dns"
)
// Static amount of RRs...
type zone struct {
name string
rrs [10000]dns.RR
size int
}
var Zone zone
func handle(d *dns.Conn, i *dns.Msg) {
if i.MsgHdr.Response == true {
return
}
handleNotify(d, i)
handleXfr(d, i)
}
func listen(addr string, e chan os.Error, tcp string) {

View File

@ -52,4 +52,23 @@ func (dns *Msg) SetAxfr(z string) {
dns.Question = make([]Question, 1)
dns.Question[0] = Question{z, TypeAXFR, ClassINET}
}
// IsIxfr/IsAxfr?
func (dns *Msg) IsAxfr() (ok bool) {
if len(dns.Question) == 0 {
return false
}
ok = dns.MsgHdr.Opcode == OpcodeQuery
ok = ok && dns.Question[0].Qclass == ClassINET
ok = ok && dns.Question[0].Qtype == TypeAXFR
return ok
}
func (dns *Msg) IsIxfr() (ok bool) {
if len(dns.Question) == 0 {
return false
}
ok = dns.MsgHdr.Opcode == OpcodeQuery
ok = ok && dns.Question[0].Qclass == ClassINET
ok = ok && dns.Question[0].Qtype == TypeIXFR
return ok
}

16
xfr.go
View File

@ -92,14 +92,14 @@ func (d *Conn) axfrWrite(q *Msg, m chan Xfr) {
out := new(Msg)
out.Id = q.Id
out.Question = q.Question
out.Answer = make([]RR, 1000)
out.Answer = make([]RR, 1001)
var soa *RR_SOA
i := 0
for r := range m {
out.Answer[i] = r.RR
if soa == nil {
if r.RR.Header().Rrtype != TypeSOA {
return
/* ... */
} else {
soa = r.RR.(*RR_SOA)
}
@ -107,22 +107,22 @@ func (d *Conn) axfrWrite(q *Msg, m chan Xfr) {
i++
if i > 1000 {
// Send it
send, _ := out.Pack()
_, err := d.Write(send)
err := d.WriteMsg(out)
if err != nil {
/* ... */
}
i = 0
// Gaat dit goed?
out.Answer = out.Answer[:0]
}
// TimersOnly foo
// TimersOnly foo for TSIG
}
// Everything is sent, only the closing soa is left.
out.Answer[i] = soa
send, _ := out.Pack()
_, err := d.Write(send)
out.Answer = out.Answer[:i]
err := d.WriteMsg(out)
if err != nil {
/* ... */
println(err.String())
}
}