Fix the error handling
Added new type (copied from net package) dns.Error that carries all errors
This commit is contained in:
parent
d4059485d5
commit
97506dafe4
|
@ -88,8 +88,12 @@ FLAGS:
|
||||||
}
|
}
|
||||||
for _, v := range qname {
|
for _, v := range qname {
|
||||||
m.Question[0] = dns.Question{v, qtype, qclass}
|
m.Question[0] = dns.Question{v, qtype, qclass}
|
||||||
|
m.SetId()
|
||||||
qr <- resolver.DnsMsg{m, nil}
|
qr <- resolver.DnsMsg{m, nil}
|
||||||
in := <-qr
|
in := <-qr
|
||||||
|
if m.Id != in.Dns.Id {
|
||||||
|
fmt.Printf("Id mismatch\n")
|
||||||
|
}
|
||||||
if in.Dns != nil {
|
if in.Dns != nil {
|
||||||
fmt.Printf("%v\n", in.Dns)
|
fmt.Printf("%v\n", in.Dns)
|
||||||
}
|
}
|
||||||
|
|
7
dns.go
7
dns.go
|
@ -29,15 +29,14 @@ import (
|
||||||
|
|
||||||
const Year68 = 2 << (32 - 1)
|
const Year68 = 2 << (32 - 1)
|
||||||
|
|
||||||
//&DNSError{Error: "name too long", Name: name}
|
type Error struct {
|
||||||
|
|
||||||
type DNSError struct {
|
|
||||||
Error string
|
Error string
|
||||||
Name string
|
Name string
|
||||||
Server string
|
Server string
|
||||||
|
Timeout bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *DNSError) String() string {
|
func (e *Error) String() string {
|
||||||
if e == nil {
|
if e == nil {
|
||||||
return "<nil>"
|
return "<nil>"
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
// Basic usage pattern for setting up a resolver:
|
// Basic usage pattern for setting up a resolver:
|
||||||
//
|
//
|
||||||
// res := new(Resolver)
|
// res := new(Resolver)
|
||||||
// ch := NewQuerier(res) // start new resolver
|
// ch := res.NewQuerier() // start new resolver
|
||||||
// res.Servers = []string{"127.0.0.1"} // set the nameserver
|
// res.Servers = []string{"127.0.0.1"} // set the nameserver
|
||||||
//
|
//
|
||||||
// m := new(Msg) // prepare a new message
|
// m := new(Msg) // prepare a new message
|
||||||
|
@ -20,6 +20,8 @@
|
||||||
// ch <- DnsMsg{m, nil} // send the query
|
// ch <- DnsMsg{m, nil} // send the query
|
||||||
// in := <-ch // wait for reply
|
// in := <-ch // wait for reply
|
||||||
//
|
//
|
||||||
|
// Note that message id checking is left to the caller
|
||||||
|
//
|
||||||
package resolver
|
package resolver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -28,6 +30,9 @@ import (
|
||||||
"dns"
|
"dns"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const packErr = "Failed to pack message"
|
||||||
|
const servErr = "No servers could be reached"
|
||||||
|
|
||||||
// When communicating with a resolver, we use this structure
|
// When communicating with a resolver, we use this structure
|
||||||
// to send packets to it, for sending Error must be nil.
|
// to send packets to it, for sending Error must be nil.
|
||||||
// A resolver responds with a reply packet and a possible error.
|
// A resolver responds with a reply packet and a possible error.
|
||||||
|
@ -82,11 +87,13 @@ func query(res *Resolver, msg chan DnsMsg) {
|
||||||
|
|
||||||
var cerr os.Error
|
var cerr os.Error
|
||||||
//if len(name) >= 256 {
|
//if len(name) >= 256 {
|
||||||
out.Dns.SetId()
|
if out.Dns.Id == 0 {
|
||||||
|
// No Id sed, set it
|
||||||
|
out.Dns.SetId()
|
||||||
|
}
|
||||||
sending, ok := out.Dns.Pack()
|
sending, ok := out.Dns.Pack()
|
||||||
if !ok {
|
if !ok {
|
||||||
//println("pack failed")
|
msg <- DnsMsg{nil, &dns.Error{Error: packErr}}
|
||||||
msg <- DnsMsg{nil, nil} // todo error
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,9 +116,7 @@ func query(res *Resolver, msg chan DnsMsg) {
|
||||||
in, err = exchange_udp(c, sending, res, true)
|
in, err = exchange_udp(c, sending, res, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check id in.id != out.id
|
// Check id in.id != out.id, should be checked in the client!
|
||||||
// TODO(mg)
|
|
||||||
|
|
||||||
c.Close()
|
c.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
|
@ -159,7 +164,7 @@ func axfr(res *Resolver, msg chan DnsMsg) {
|
||||||
out.Dns.SetId()
|
out.Dns.SetId()
|
||||||
sending, ok := out.Dns.Pack()
|
sending, ok := out.Dns.Pack()
|
||||||
if !ok {
|
if !ok {
|
||||||
msg <- DnsMsg{nil, nil}
|
msg <- DnsMsg{nil, &dns.Error{Error: packErr}}
|
||||||
}
|
}
|
||||||
SERVER:
|
SERVER:
|
||||||
for i := 0; i < len(res.Servers); i++ {
|
for i := 0; i < len(res.Servers); i++ {
|
||||||
|
@ -211,6 +216,7 @@ func axfr(res *Resolver, msg chan DnsMsg) {
|
||||||
close(msg)
|
close(msg)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// TODO(mg) check in/out ID here
|
||||||
// With 1 successfull server, we dont get here, so
|
// With 1 successfull server, we dont get here, so
|
||||||
// We've failed
|
// We've failed
|
||||||
msg <- DnsMsg{nil, err} // TODO Err
|
msg <- DnsMsg{nil, err} // TODO Err
|
||||||
|
@ -244,7 +250,9 @@ func exchange_udp(c net.Conn, m []byte, r *Resolver, send bool) (*dns.Msg, os.Er
|
||||||
if send {
|
if send {
|
||||||
_, err := c.Write(m)
|
_, err := c.Write(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//println("error writing")
|
if e, ok := err.(net.Error); ok && e.Timeout() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,12 +261,10 @@ func exchange_udp(c net.Conn, m []byte, r *Resolver, send bool) (*dns.Msg, os.Er
|
||||||
buf := make([]byte, dns.DefaultMsgSize) // More than enough???
|
buf := make([]byte, dns.DefaultMsgSize) // More than enough???
|
||||||
n, err := c.Read(buf)
|
n, err := c.Read(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
//println("error reading")
|
// If timeout try the next
|
||||||
//println(err.String())
|
if e, ok := err.(net.Error); ok && e.Timeout() {
|
||||||
// More Go foo needed
|
continue
|
||||||
//if e, ok := err.(Error); ok && e.Timeout() {
|
}
|
||||||
// continue
|
|
||||||
//}
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
buf = buf[0:n]
|
buf = buf[0:n]
|
||||||
|
@ -268,7 +274,7 @@ func exchange_udp(c net.Conn, m []byte, r *Resolver, send bool) (*dns.Msg, os.Er
|
||||||
}
|
}
|
||||||
return in, nil
|
return in, nil
|
||||||
}
|
}
|
||||||
return nil, nil // todo error
|
return nil, &dns.Error{Error: servErr}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Up to res.Attempts attempts.
|
// Up to res.Attempts attempts.
|
||||||
|
@ -300,12 +306,18 @@ func exchange_tcp(c net.Conn, m []byte, r *Resolver, send bool) (*dns.Msg, os.Er
|
||||||
// With DNS over TCP we first send the length
|
// With DNS over TCP we first send the length
|
||||||
_, err := c.Write(ls)
|
_, err := c.Write(ls)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if e, ok := err.(net.Error); ok && e.Timeout() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// And then send the message
|
// And then send the message
|
||||||
_, err = c.Write(m)
|
_, err = c.Write(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if e, ok := err.(net.Error); ok && e.Timeout() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,6 +326,9 @@ func exchange_tcp(c net.Conn, m []byte, r *Resolver, send bool) (*dns.Msg, os.Er
|
||||||
// The server replies with two bytes length
|
// The server replies with two bytes length
|
||||||
_, err := c.Read(lr)
|
_, err := c.Read(lr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if e, ok := err.(net.Error); ok && e.Timeout() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
length = uint16(lr[0])<<8 | uint16(lr[1])
|
length = uint16(lr[0])<<8 | uint16(lr[1])
|
||||||
|
@ -323,24 +338,29 @@ func exchange_tcp(c net.Conn, m []byte, r *Resolver, send bool) (*dns.Msg, os.Er
|
||||||
|
|
||||||
n, err = c.Read(buf)
|
n, err = c.Read(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if e, ok := err.(net.Error); ok && e.Timeout() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
i := n
|
i := n
|
||||||
if i < int(length) {
|
if i < int(length) {
|
||||||
n, err = c.Read(buf[i:])
|
n, err = c.Read(buf[i:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if e, ok := err.(net.Error); ok && e.Timeout() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
i += n
|
i += n
|
||||||
}
|
}
|
||||||
in := new(dns.Msg)
|
in := new(dns.Msg)
|
||||||
if !in.Unpack(buf) {
|
if !in.Unpack(buf) {
|
||||||
// println("unpacking went wrong")
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return in, nil
|
return in, nil
|
||||||
}
|
}
|
||||||
return nil, nil // todo error
|
return nil, &dns.Error{Error: servErr}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if he SOA record exists in the Answer section of
|
// Check if he SOA record exists in the Answer section of
|
||||||
|
|
Loading…
Reference in New Issue