Fix examples and API additions

This commit is contained in:
Miek Gieben 2011-03-23 09:50:38 +01:00
parent 1503661970
commit 8b70e31c41
8 changed files with 88 additions and 79 deletions

View File

@ -19,19 +19,13 @@ func main() {
c := make(chan dns.Xfr)
m := new(dns.Msg)
m.Question = make([]dns.Question, 1)
if *serial > 0 {
m.Question[0] = dns.Question{zone, dns.TypeIXFR, dns.ClassINET}
soa := new(dns.RR_SOA)
soa.Hdr = dns.RR_Header{zone, dns.TypeSOA, dns.ClassINET, 14400, 0}
soa.Serial = uint32(*serial)
m.Ns = make([]dns.RR, 1)
m.Ns[0] = soa
m.SetIxfr(zone, uint32(*serial))
} else {
m.Question[0] = dns.Question{zone, dns.TypeAXFR, dns.ClassINET}
m.SetAxfr(zone)
}
go res.Xfr(m, nil, c)
go res.Xfr(m, c)
for x := range c {
fmt.Printf("%v %v\n",x.Add, x.RR)
}

View File

@ -3,6 +3,7 @@
# license that can be found in the LICENSE file.
include $(GOROOT)/src/Make.inc
TARG=xfrprx
GOFILES=xfrprx.go
GOFILES=xfrprx.go\
xfr.go
DEPS=../../
include $(GOROOT)/src/Make.cmd

View File

@ -1,63 +1,45 @@
package main
// Xfrprx is a proxy that intercepts notify messages
// and then performs a ixfr/axfr to get the new
// zone contents.
// This zone is then checked cryptographically is
// everything is correct.
// If a new DNSKEY record is seen for the apex and
// it validates it writes this record to disk and
// this new key will be used in future validations.
import (
"os"
"os/signal"
"fmt"
"dns"
"net"
"fmt"
)
func reply(d *dns.Conn, i *dns.Msg) []byte {
return nil
}
func handle(d *dns.Conn, i *dns.Msg) {
if i.MsgHdr.Response == true {
return
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 {
return
}
d.Write(answer)
doXfr(i)
}
answer := reply(d, i)
d.Write(answer)
}
func listen(addr string, e chan os.Error, tcp string) {
switch tcp {
case "tcp":
err := dns.ListenAndServeTCP(addr, handle)
e <- err
case "udp":
err := dns.ListenAndServeUDP(addr, handle)
e <- err
func doXfr(i *dns.Msg) ([]dns.RR, os.Error) {
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)
// Fill and setup the dns.Conn.
d := new(dns.Conn)
c, err := net.Dial("tcp", "", "127.0.0.1:53")
if err != nil {
return nil, err
}
return
}
func main() {
err := make(chan os.Error)
go listen("127.0.0.1:8053", err, "tcp")
go listen("[::1]:8053", err, "udp")
go listen("127.0.0.1:8053", err, "tcp")
go listen("[::1]:8053", err, "udp")
forever:
for {
select {
case e := <-err:
fmt.Printf("Error received, stopping: %s\n", e.String())
break forever
case <-signal.Incoming:
fmt.Printf("Signal received, stopping")
break forever
}
}
close(err)
fmt.Printf("Calling 127.0.0.1 successful\n")
d.TCP = c.(*net.TCPConn)
d.Addr = d.TCP.RemoteAddr()
go d.XfrRead(q, m)
for x := range m {
fmt.Printf("%v %v\n", x.Add, x.RR)
}
return nil, nil
}

View File

@ -12,21 +12,15 @@ package main
import (
"os"
"os/signal"
// "net"
"fmt"
"dns"
)
func reply(d *dns.Conn, i *dns.Msg) []byte {
return nil
}
func handle(d *dns.Conn, i *dns.Msg) {
if i.MsgHdr.Response == true {
return
}
answer := reply(d, i)
d.Write(answer)
handleNotify(d, i)
}
func listen(addr string, e chan os.Error, tcp string) {
@ -44,8 +38,8 @@ func listen(addr string, e chan os.Error, tcp string) {
func main() {
err := make(chan os.Error)
go listen("127.0.0.1:8053", err, "tcp")
go listen("[::1]:8053", err, "udp")
go listen("127.0.0.1:8053", err, "tcp")
go listen("[::1]:8053", err, "tcp")
go listen("127.0.0.1:8053", err, "udp")
go listen("[::1]:8053", err, "udp")
forever:

View File

@ -3,12 +3,14 @@ package dns
// Everything is assumed in the ClassINET class
// Create a reply packet.
func (dns *Msg) SetReply(id uint16) {
dns.MsgHdr.Id = id
func (dns *Msg) SetReply(request *Msg) {
dns.MsgHdr.Id = request.MsgHdr.Id
dns.MsgHdr.Authoritative = true
dns.MsgHdr.Response = true
dns.MsgHdr.Opcode = OpcodeQuery
dns.MsgHdr.Rcode = RcodeSuccess
dns.Question = make([]Question, 1)
dns.Question[0] = request.Question[0]
}
// IsReply?
@ -23,11 +25,11 @@ func (dns *Msg) SetNotify(z string, class uint16) {
}
// Is a dns msg a valid notify packet?
func (dns *Msg) IsNotify() bool {
ok := dns.MsgHdr.Opcode == OpcodeNotify
func (dns *Msg) IsNotify() (ok bool) {
if len(dns.Question) == 0 {
ok = false
return false
}
ok = dns.MsgHdr.Opcode == OpcodeNotify
ok = ok && dns.Question[0].Qclass == ClassINET
ok = ok && dns.Question[0].Qtype == TypeSOA
return ok

29
dns.go
View File

@ -84,6 +84,34 @@ func (d *Conn) NewBuffer() []byte {
return nil
}
func (d *Conn) ReadMsg(m *Msg) os.Error {
in := d.NewBuffer()
n, err := d.Read(in)
if err != nil {
return err
}
in = in[:n]
ok := m.Unpack(in)
if !ok {
return &Error{Error: "Failed to unpack"}
}
return nil
}
func (d *Conn) WriteMsg(m *Msg) os.Error {
out, ok := m.Pack()
if !ok {
return &Error{Error: "Failed to pack"}
}
n, err := d.Write(out)
if err != nil {
return err
}
if n != len(out) {
return &Error{Error: "Short write"}
}
return nil
}
func (d *Conn) Read(p []byte) (n int, err os.Error) {
if d.UDP != nil && d.TCP != nil {
@ -261,7 +289,6 @@ func (d *Conn) Exchange(request []byte, nosend bool) (reply []byte, err os.Error
return
}
type RR interface {
Header() *RR_Header
String() string

View File

@ -67,16 +67,20 @@ func (res *Resolver) QueryTsig(q *Msg, tsig *Tsig) (d *Msg, err os.Error) {
t := time.Nanoseconds()
if res.Tcp {
c, err = net.Dial("tcp", "", server)
if err != nil {
continue
}
d.TCP = c.(*net.TCPConn)
d.Addr = d.TCP.RemoteAddr()
} else {
c, err = net.Dial("udp", "", server)
if err != nil {
continue
}
d.UDP = c.(*net.UDPConn)
d.Addr = d.UDP.RemoteAddr()
}
if err != nil {
continue
}
inb, err = d.Exchange(sending, false)
if err != nil {
continue

5
xfr.go
View File

@ -17,6 +17,11 @@ type Xfr struct {
// Msg tells use what to do
func (d *Conn) XfrRead(q *Msg, m chan Xfr) {
// Send q first.
err := d.WriteMsg(q)
if err != nil {
return
}
switch q.Question[0].Qtype {
case TypeAXFR:
d.axfrRead(q, m)