Better error handling

This commit is contained in:
Miek Gieben 2011-03-21 17:55:14 +01:00
parent 72c6ff37eb
commit 7a466c2f73
2 changed files with 27 additions and 15 deletions

View File

@ -88,14 +88,6 @@ func (res *Resolver) Query(q *Msg, tsig *Tsig) (d *Msg, err os.Error) {
return in, nil return in, nil
} }
// Xfr is used in communicating with *xfr functions.
// This structure is returned on the channel.
type Xfr struct {
Add bool // true is to be added, otherwise false
RR
Err os.Error
}
func (res *Resolver) Xfr(q *Msg, t *Tsig, m chan Xfr) { func (res *Resolver) Xfr(q *Msg, t *Tsig, m chan Xfr) {
port, err := check(res, q) port, err := check(res, q)
if err != nil { if err != nil {
@ -120,7 +112,7 @@ Server:
_, err = d.Write(sending) _, err = d.Write(sending)
if err != nil { if err != nil {
println(err.String()) continue Server
} }
d.XfrRead(q, m) // check d.XfrRead(q, m) // check
} }

32
xfr.go
View File

@ -1,8 +1,20 @@
package dns package dns
import (
"os"
)
// Outgoing AXFR and IXFR implementations // Outgoing AXFR and IXFR implementations
// error handling?? // error handling??
// Xfr is used in communicating with *xfr functions.
// This structure is returned on the channel.
type Xfr struct {
Add bool // true is to be added, otherwise false
RR
Err os.Error
}
// Msg tells use what to do // Msg tells use what to do
func (d *Conn) XfrRead(q *Msg, m chan Xfr) { func (d *Conn) XfrRead(q *Msg, m chan Xfr) {
switch q.Question[0].Qtype { switch q.Question[0].Qtype {
@ -30,28 +42,32 @@ func (d *Conn) axfrRead(q *Msg, m chan Xfr) {
inb := make([]byte, MaxMsgSize) inb := make([]byte, MaxMsgSize)
n, err := d.Read(inb) n, err := d.Read(inb)
if err != nil { if err != nil {
m <- Xfr{true, nil, err}
return return
} }
inb = inb[:n] inb = inb[:n]
if !in.Unpack(inb) { if !in.Unpack(inb) {
m <- Xfr{true, nil, &Error{Error: "Failed to unpack"}}
return return
} }
if in.Id != q.Id { if in.Id != q.Id {
m <- Xfr{true, nil, &Error{Error: "Id mismatch"}}
return return
} }
if first { if first {
if !checkXfrSOA(in, true) { if !checkXfrSOA(in, true) {
m <- Xfr{true, nil, &Error{Error: "SOA not first record"}}
return return
} }
first = !first first = !first
} }
if !first { if !first {
if d.Tsig != nil { if d.Tsig != nil {
d.Tsig.TimersOnly = true // Subsequent envelopes use this d.Tsig.TimersOnly = true // Subsequent envelopes use this
} }
if !checkXfrSOA(in, false) { if !checkXfrSOA(in, false) {
// Soa record not the last one // Soa record not the last one
sendMsg(in, m, false) sendMsg(in, m, false)
@ -120,14 +136,17 @@ func (d *Conn) ixfrRead(q *Msg, m chan Xfr) {
} }
n, err := d.Read(inb) n, err := d.Read(inb)
if err != nil { if err != nil {
m <- Xfr{true, nil, err}
return return
} }
inb = inb[:n] inb = inb[:n]
if !in.Unpack(inb) { if !in.Unpack(inb) {
m <- Xfr{true, nil, &Error{Error: "Failed to unpack"}}
return return
} }
if in.Id != q.Id { if in.Id != q.Id {
m <- Xfr{true, nil, &Error{Error: "Id mismatch"}}
return return
} }
@ -139,6 +158,7 @@ func (d *Conn) ixfrRead(q *Msg, m chan Xfr) {
// But still check if the returned answer is ok // But still check if the returned answer is ok
if !checkXfrSOA(in, true) { if !checkXfrSOA(in, true) {
m <- Xfr{true, nil, &Error{Error: "SOA not first record"}}
return return
} }
// This serial is important // This serial is important
@ -149,9 +169,9 @@ func (d *Conn) ixfrRead(q *Msg, m chan Xfr) {
// Now we need to check each message for SOA records, to see what we need to do // Now we need to check each message for SOA records, to see what we need to do
x.Add = true x.Add = true
if !first { if !first {
if d.Tsig != nil { if d.Tsig != nil {
d.Tsig.TimersOnly = true d.Tsig.TimersOnly = true
} }
for k, r := range in.Answer { for k, r := range in.Answer {
// If the last record in the IXFR contains the servers' SOA, we should quit // If the last record in the IXFR contains the servers' SOA, we should quit
if r.Header().Rrtype == TypeSOA { if r.Header().Rrtype == TypeSOA {