Framework for xfr started in resolver
This commit is contained in:
parent
82c954bead
commit
1c9282ed7e
51
msg.go
51
msg.go
|
@ -27,6 +27,31 @@ import (
|
|||
|
||||
const DefaultMsgSize = 4096
|
||||
|
||||
// A manually-unpacked version of (id, bits).
|
||||
// This is in its own struct for easy printing.
|
||||
type MsgHdr struct {
|
||||
Id uint16
|
||||
Response bool
|
||||
Opcode int
|
||||
Authoritative bool
|
||||
Truncated bool
|
||||
RecursionDesired bool
|
||||
RecursionAvailable bool
|
||||
Zero bool
|
||||
AuthenticatedData bool
|
||||
CheckingDisabled bool
|
||||
Rcode int
|
||||
}
|
||||
|
||||
// The layout of a DNS message.
|
||||
type Msg struct {
|
||||
MsgHdr
|
||||
Question []Question
|
||||
Answer []RR
|
||||
Ns []RR
|
||||
Extra []RR
|
||||
}
|
||||
|
||||
// Packing and unpacking.
|
||||
//
|
||||
// All the packers and unpackers take a (msg []byte, off int)
|
||||
|
@ -536,22 +561,6 @@ func unpackRR(msg []byte, off int) (rr RR, off1 int, ok bool) {
|
|||
|
||||
// Usable representation of a DNS packet.
|
||||
|
||||
// A manually-unpacked version of (id, bits).
|
||||
// This is in its own struct for easy printing.
|
||||
type MsgHdr struct {
|
||||
Id uint16
|
||||
Response bool
|
||||
Opcode int
|
||||
Authoritative bool
|
||||
Truncated bool
|
||||
RecursionDesired bool
|
||||
RecursionAvailable bool
|
||||
Zero bool
|
||||
AuthenticatedData bool
|
||||
CheckingDisabled bool
|
||||
Rcode int
|
||||
}
|
||||
|
||||
// Convert a MsgHdr to a string, mimic the way Dig displays headers:
|
||||
//;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48404
|
||||
//;; flags: qr aa rd ra;
|
||||
|
@ -594,16 +603,6 @@ func (h *MsgHdr) String() string {
|
|||
return s
|
||||
}
|
||||
|
||||
// The layout of a DNS message.
|
||||
type Msg struct {
|
||||
MsgHdr
|
||||
Question []Question
|
||||
Answer []RR
|
||||
Ns []RR
|
||||
Extra []RR
|
||||
}
|
||||
|
||||
|
||||
func (dns *Msg) Pack() (msg []byte, ok bool) {
|
||||
var dh Header
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ func NewQuerier(res *Resolver) (ch chan DnsMsg) {
|
|||
|
||||
// The query function.
|
||||
func query(res *Resolver, msg chan DnsMsg) {
|
||||
// TODO port number, error checking, robustness
|
||||
// error checking, robustness
|
||||
var c net.Conn
|
||||
var err os.Error
|
||||
var in *dns.Msg
|
||||
|
@ -138,6 +138,61 @@ func NewXfer(res *Resolver) (ch chan DnsMsg) {
|
|||
}
|
||||
|
||||
func axfr(res *Resolver, msg chan DnsMsg) {
|
||||
// open socket
|
||||
// call exchange_tcp
|
||||
// check for soa
|
||||
// repeat if no soa
|
||||
// close channel
|
||||
var port string
|
||||
var err os.Error
|
||||
var in *dns.Msg
|
||||
if res.Port == "" {
|
||||
port = "53"
|
||||
} else {
|
||||
port = res.Port
|
||||
}
|
||||
var sending []byte
|
||||
// out.Dns.Id = uint16(rand.Int()) ^ uint16(time.Nanoseconds())
|
||||
// sending, ok := out.Dns.Pack()
|
||||
for i:=0; i<len(res.Servers); i++ {
|
||||
server := res.Servers[i] + port
|
||||
c, cerr := net.Dial("tcp", "", server)
|
||||
if cerr != nil {
|
||||
err = cerr
|
||||
continue
|
||||
}
|
||||
|
||||
first := true
|
||||
for {
|
||||
|
||||
in, cerr = exchange_tcp(c, sending, res)
|
||||
if cerr != nil {
|
||||
err = cerr
|
||||
continue
|
||||
}
|
||||
if first {
|
||||
if ! checkSOA(in, true) {
|
||||
// SOA record not there...
|
||||
return // ?
|
||||
}
|
||||
first = !first
|
||||
// send in to message
|
||||
|
||||
continue
|
||||
} else {
|
||||
if ! checkSOA(in, false) {
|
||||
// Soa record not the last one
|
||||
// return packet
|
||||
// next
|
||||
} else {
|
||||
// last one
|
||||
// close channel
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
err = err
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -254,3 +309,17 @@ func exchange_tcp(c net.Conn, m []byte, r *Resolver) (*dns.Msg, os.Error) {
|
|||
}
|
||||
return nil, nil // todo error
|
||||
}
|
||||
|
||||
// Check if he SOA record exists in the Answer section of
|
||||
// the packet. If first is true the first RR must be a soa
|
||||
// if false, the last one should be a SOA
|
||||
func checkSOA(in *dns.Msg, first bool) bool {
|
||||
if len(in.Answer) > 0 {
|
||||
if first {
|
||||
return in.Answer[0].Header().Rrtype == dns.TypeSOA
|
||||
} else {
|
||||
return in.Answer[len(in.Answer)].Header().Rrtype == dns.TypeSOA
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue