API is taking shape
This commit is contained in:
parent
62fc0f05f7
commit
2b7d2203fb
|
@ -9,28 +9,22 @@ import (
|
|||
|
||||
func main() {
|
||||
var serial *int = flag.Int("serial", 0, "Perform an IXFR with the given serial")
|
||||
var nameserver *string = flag.String("ns", "127.0.0.1", "Query this nameserver")
|
||||
var nameserver *string = flag.String("ns", "127.0.0.1:53", "Query this nameserver")
|
||||
flag.Parse()
|
||||
zone := flag.Arg(flag.NArg()-1)
|
||||
|
||||
res := new(dns.Resolver)
|
||||
res.FromFile("/etc/resolv.conf")
|
||||
res.Servers[0] = *nameserver
|
||||
|
||||
c := make(chan dns.Xfr)
|
||||
d := new(dns.Conn)
|
||||
m := new(dns.Msg)
|
||||
|
||||
d.RemoteAddr = *nameserver
|
||||
if *serial > 0 {
|
||||
m.SetIxfr(zone, uint32(*serial))
|
||||
} else {
|
||||
m.SetAxfr(zone)
|
||||
}
|
||||
go res.Xfr(m, c)
|
||||
go d.XfrRead(m, c)
|
||||
for x := range c {
|
||||
// if x.Err != nil {
|
||||
// fmt.Printf("%v\n",x.Err)
|
||||
// } else {
|
||||
fmt.Printf("%v %v\n",x.Add, x.RR)
|
||||
// }
|
||||
fmt.Printf("%v %v %v\n",x.Add, x.RR, x.Err)
|
||||
}
|
||||
}
|
||||
|
|
46
dns.go
46
dns.go
|
@ -16,17 +16,7 @@
|
|||
// The package dns supports querying, incoming/outgoing Axfr/Ixfr, TSIG, EDNS0,
|
||||
// dynamic updates, notifies and DNSSEC validation/signing.
|
||||
//
|
||||
// Use patter for simple querying:
|
||||
//
|
||||
// res := new(Resolver)
|
||||
// res.Servers = []string{"127.0.0.1"}
|
||||
// m := new(Msg)
|
||||
// m.MsgHdr.Recursion_desired = true
|
||||
// m.Question = make([]Question, 1)
|
||||
// m.Question[0] = Question{"miek.nl", TypeSOA, ClassINET}
|
||||
// in, err := res.Query(m)
|
||||
//
|
||||
// Asynchronize querying the DNS is done by using the Conn structure.
|
||||
// (Asynchronize) querying the DNS is done by using the Conn structure.
|
||||
// Basic use pattern for creating such a resolver:
|
||||
//
|
||||
// func handle(d *Conn, m *Msg, q chan Query) { /* handle query */ }
|
||||
|
@ -36,6 +26,11 @@
|
|||
// d := new(Conn)
|
||||
// d.RemoteAddr = "8.8.8.8:53"
|
||||
//
|
||||
// // Create message with the desired options.
|
||||
// m.MsgHdr.Recursion_desired = true
|
||||
// m.Question = make([]Question, 1)
|
||||
// m.Question[0] = Question{"miek.nl", TypeSOA, ClassINET}
|
||||
//
|
||||
// in <- Query{Msg: m, Conn: d} // Send query using the above message
|
||||
// reply := <-out // Listen for replie(s)
|
||||
//
|
||||
|
@ -112,13 +107,34 @@ type Conn struct {
|
|||
// The remote addr which is going to be dialed.
|
||||
RemoteAddr string
|
||||
|
||||
// The local addr used for outgoing queries
|
||||
LocalAddr string
|
||||
|
||||
// Mangle the packet before writing it be feeding
|
||||
// it through this function.
|
||||
Mangle func([]byte) []byte
|
||||
|
||||
// rtt times?
|
||||
}
|
||||
|
||||
// Dial, with minimum filled out Conn (RemoteAddr and LocalAddr)
|
||||
func (d *Conn) Dial(n string) os.Error {
|
||||
c, err := net.Dial(n, d.LocalAddr, d.RemoteAddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch n {
|
||||
case "tcp":
|
||||
d.TCP = c.(*net.TCPConn)
|
||||
d.Addr = d.TCP.RemoteAddr()
|
||||
d.Port = d.TCP.RemoteAddr().(*net.TCPAddr).Port
|
||||
case "udp":
|
||||
d.UDP = c.(*net.UDPConn)
|
||||
d.Addr = d.UDP.RemoteAddr()
|
||||
d.Port = d.UDP.RemoteAddr().(*net.UDPAddr).Port
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
// Dial connects to the remote address raddr on the network net.
|
||||
// If the string laddr is not empty, it is used as the local address
|
||||
// for the connection. Any errors are return in err otherwise err is nil.
|
||||
|
@ -148,6 +164,8 @@ func (d *Conn) SetTCPConn(l *net.TCPConn, a net.Addr) {
|
|||
d.UDP = nil
|
||||
if a == nil {
|
||||
d.Addr = l.RemoteAddr()
|
||||
} else {
|
||||
d.Addr = a
|
||||
}
|
||||
d.Port = d.Addr.(*net.TCPAddr).Port
|
||||
}
|
||||
|
@ -159,6 +177,8 @@ func (d *Conn) SetUDPConn(l *net.UDPConn, a net.Addr) {
|
|||
d.UDP = l
|
||||
if a == nil {
|
||||
d.Addr = l.RemoteAddr()
|
||||
} else {
|
||||
d.Addr = a
|
||||
}
|
||||
d.Port = d.Addr.(*net.UDPAddr).Port
|
||||
}
|
||||
|
|
|
@ -17,7 +17,8 @@ type Query struct {
|
|||
// The query message.
|
||||
Msg *Msg
|
||||
// A Conn. Its only required to fill out Conn.RemoteAddr.
|
||||
// The rest of the structure is filled in by the Query Functions.
|
||||
// Optionally you may set Conn.Tsig.
|
||||
// The rest of the structure is filled by the Query Functions.
|
||||
Conn *Conn
|
||||
// Any erros when querying are returned in Err. The caller
|
||||
// should just set this to nil.
|
||||
|
@ -30,7 +31,6 @@ type Query struct {
|
|||
func QueryUDP(in, out chan Query, f func(*Conn, *Msg, chan Query)) {
|
||||
query("udp", in, out, f)
|
||||
}
|
||||
// Shoudl the chan be *Query??
|
||||
|
||||
// QueryTCP handles one query. It reads an incoming request from
|
||||
// the in channel. The function f is executed in a seperate
|
||||
|
@ -46,7 +46,7 @@ func query(n string, in, out chan Query, f func(*Conn, *Msg, chan Query)) {
|
|||
case q := <-in:
|
||||
c, err := net.Dial(n, "", q.Conn.RemoteAddr)
|
||||
if err != nil {
|
||||
//out <- nil
|
||||
out <- Query{Err: err}
|
||||
}
|
||||
if n == "tcp" {
|
||||
q.Conn.SetTCPConn(c.(*net.TCPConn), nil)
|
||||
|
|
9
xfr.go
9
xfr.go
|
@ -21,6 +21,15 @@ type Xfr struct {
|
|||
// section contains an AXFR type an Axfr is performed. If q's question
|
||||
// section contains an IXFR type an Ixfr is performed.
|
||||
func (d *Conn) XfrRead(q *Msg, m chan Xfr) {
|
||||
if d.TCP == nil && d.UDP == nil {
|
||||
// No connection yet
|
||||
if err := d.Dial("tcp"); err != nil {
|
||||
m <- Xfr{true, nil, err}
|
||||
close(m)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Send q first.
|
||||
err := d.WriteMsg(q)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue