Create xfr proxy
This commit is contained in:
parent
8b70e31c41
commit
8b2882673f
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
21
defaults.go
21
defaults.go
|
@ -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
16
xfr.go
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue