normalize errors

This commit is contained in:
Miek Gieben 2011-03-25 11:19:35 +01:00
parent 9ac4df6b1d
commit 8aa88a0bd3
8 changed files with 53 additions and 46 deletions

30
dns.go
View File

@ -4,7 +4,7 @@
// Extended and bugfixes by Miek Gieben
// Package dns implements a full featured interface to the DNS.
// The package allows full control over what is send out to the DNS.
// The package allows complete control over what is send out to the DNS.
//
// Resource records are native types. They are not stored in wire format.
// Basic usage pattern for creating a new resource record:
@ -16,7 +16,8 @@
// The package dns supports querying, incoming/outgoing Axfr/Ixfr, TSIG, EDNS0,
// dynamic updates, notifies and DNSSEC validation/signing.
//
// Basic use pattern for creating a resolver:
// Querying the DNS is done by using a Resolver structure. Basic use pattern for creating
// a resolver:
//
// res := new(Resolver)
// res.Servers = []string{"127.0.0.1"}
@ -26,7 +27,7 @@
// m.Question[0] = Question{"miek.nl", TypeSOA, ClassINET}
// in, err := res.Query(m)
//
//
// Server side programming is also supported.
// Basic use pattern for creating an UDP DNS server:
//
// func handle(d *dns.Conn, i *dns.Msg) { /* handle request */ }
@ -40,9 +41,8 @@
//
package dns
// ErrShortWrite is defined in io, use that!
import (
"io"
"os"
"net"
"strconv"
@ -123,7 +123,7 @@ func (d *Conn) ReadMsg(m *Msg) os.Error {
in = in[:n]
ok := m.Unpack(in)
if !ok {
return &Error{Error: "Failed to unpack"}
return ErrUnpack
}
return nil
}
@ -133,7 +133,7 @@ func (d *Conn) ReadMsg(m *Msg) os.Error {
func (d *Conn) WriteMsg(m *Msg) os.Error {
out, ok := m.Pack()
if !ok {
return &Error{Error: "Failed to pack"}
return ErrPack
}
_, err := d.Write(out)
if err != nil {
@ -147,7 +147,7 @@ func (d *Conn) WriteMsg(m *Msg) os.Error {
// reading that error is returned; otherwise err is nil.
func (d *Conn) Read(p []byte) (n int, err os.Error) {
if d.UDP != nil && d.TCP != nil {
return 0, &Error{Error: "UDP and TCP or both non-nil"}
return 0, ErrConn
}
switch {
case d.UDP != nil:
@ -160,7 +160,7 @@ func (d *Conn) Read(p []byte) (n int, err os.Error) {
d.Port = addr.(*net.UDPAddr).Port
case d.TCP != nil:
if len(p) < 1 {
return 0, &Error{Error: "Buffer too small to read"}
return 0, io.ErrShortBuffer
}
n, err = d.TCP.Read(p[0:2])
if err != nil || n != 2 {
@ -170,10 +170,10 @@ func (d *Conn) Read(p []byte) (n int, err os.Error) {
d.Port = d.TCP.RemoteAddr().(*net.TCPAddr).Port
l, _ := unpackUint16(p[0:2], 0)
if l == 0 {
return 0, &Error{Error: "received nil msg length", Server: d.Addr}
return 0, ErrShortRead
}
if int(l) > len(p) {
return int(l), &Error{Error: "Buffer too small to read"}
return int(l), io.ErrShortBuffer
}
n, err = d.TCP.Read(p[:l])
if err != nil {
@ -204,7 +204,7 @@ func (d *Conn) Read(p []byte) (n int, err os.Error) {
// that error is returned; otherwise err is nil
func (d *Conn) Write(p []byte) (n int, err os.Error) {
if d.UDP != nil && d.TCP != nil {
return 0, &Error{Error: "UDP and TCP or both non-nil"}
return 0, ErrConn
}
var attempts int
@ -248,7 +248,7 @@ func (d *Conn) Write(p []byte) (n int, err os.Error) {
return n, err
}
if n != 2 {
return n, &Error{Error: "Write failure"}
return n, io.ErrShortWrite
}
n, err = d.TCP.Write(q)
if err != nil {
@ -279,7 +279,7 @@ func (d *Conn) Write(p []byte) (n int, err os.Error) {
// errors are returned in err; otherwise it is nil.
func (d *Conn) Close() (err os.Error) {
if d.UDP != nil && d.TCP != nil {
return &Error{Error: "UDP and TCP or both non-nil"}
return ErrConn
}
switch {
case d.UDP != nil:
@ -295,7 +295,7 @@ func (d *Conn) Close() (err os.Error) {
func (d *Conn) SetTimeout() (err os.Error) {
var sec int64
if d.UDP != nil && d.TCP != nil {
return &Error{Error: "UDP and TCP or both non-nil"}
return ErrConn
}
sec = int64(d.Timeout)
if sec == 0 {

View File

@ -5,7 +5,7 @@ import (
"encoding/hex"
)
// EDNS0 Options
// EDNS0 Option codes.
const (
_ = iota
OptionCodeLLQ // not used

View File

@ -23,14 +23,14 @@ func (r *RR_DNSKEY) Generate(bits int) (PrivateKey, os.Error) {
switch r.Algorithm {
case AlgRSAMD5, AlgRSASHA1, AlgRSASHA256:
if bits < 512 || bits > 4096 {
return nil, &Error{Error: "Size not in range [512..4096]"}
return nil, ErrKeySize
}
case AlgRSASHA512:
if bits < 1024 || bits > 4096 {
return nil, &Error{Error: "Size not in range [1024..4096]"}
return nil, ErrKeySize
}
default:
return nil, &Error{Error: "Algorithm not recognized"}
return nil, ErrAlg
}
switch r.Algorithm {
@ -100,12 +100,12 @@ func (k *RR_DNSKEY) ReadPrivateKey(q io.Reader) (PrivateKey, os.Error) {
switch left {
case "Private-key-format:":
if right != "v1.3" {
return nil, &Error{Error: "v1.3 supported"}
return nil, ErrPrivKey
}
case "Algorithm:":
a, _ := strconv.Atoi(right)
if a == 0 {
return nil, &Error{Error: "incorrect algorithm"}
return nil, ErrAlg
}
k.Algorithm = uint8(a)
case "Modulus:", "PublicExponent:", "PrivateExponent:", "Prime1:", "Prime2:":
@ -140,13 +140,13 @@ func (k *RR_DNSKEY) ReadPrivateKey(q io.Reader) (PrivateKey, os.Error) {
case "Created:", "Publish:", "Activate:":
/* not used in Go (yet) */
default:
return nil, &Error{Error: "Private key file not recognized"}
return nil, ErrKey
}
}
line, _, err = r.ReadLine()
}
if ! k.setPublicKeyRSA(p.PublicKey.E, p.PublicKey.N) {
return nil, &Error{Error: "Failed to set public key"}
return nil, ErrKey
}
return p, nil
}

15
msg.go
View File

@ -27,6 +27,21 @@ import (
"encoding/hex"
)
var ErrUnpack os.Error = &Error{Error: "unpacking failed"}
var ErrPack os.Error = &Error{Error: "packing failed"}
var ErrId os.Error = &Error{Error: "id mismatch"}
var ErrShortRead os.Error = &Error{Error: "short read"}
var ErrConn os.Error = &Error{Error: "conn holds both UDP and TCP connection"}
var ErrServ os.Error = &Error{Error: "no servers could be reached"}
var ErrKey os.Error = &Error{Error: "bad key"}
var ErrPrivKey os.Error = &Error{Error: "bad private key"}
var ErrKeySize os.Error = &Error{Error: "bad key size"}
var ErrAlg os.Error = &Error{Error: "bad algorithm"}
var ErrTime os.Error = &Error{Error: "bad time"}
var ErrSig os.Error = &Error{Error: "bad signature"}
var ErrSigGen os.Error = &Error{Error: "bad signature generation"}
var ErrXfrSoa os.Error = &Error{Error: "no SOA seen"}
// A manually-unpacked version of (id, bits).
// This is in its own struct for easy printing.
type MsgHdr struct {

View File

@ -12,14 +12,6 @@ import (
"time"
)
// Todo(MG) put in dns.go
const ErrPack = "Failed to pack message"
const ErrUnpack = ""
const ErrServ = "No servers could be reached"
const ErrTsigKey = ""
const ErrTsigTime = ""
const ErrTsig = ""
type Resolver struct {
Servers []string // servers to use
Search []string // suffixes to append to local name
@ -50,7 +42,7 @@ func (res *Resolver) QueryTsig(q *Msg, tsig *Tsig) (d *Msg, err os.Error) {
sending, ok := q.Pack()
if !ok {
return nil, &Error{Error: ErrPack}
return nil, ErrPack
}
if res.Mangle != nil {
sending = res.Mangle(sending)

12
tsig.go
View File

@ -101,7 +101,7 @@ func (t *Tsig) Generate(msg []byte) ([]byte, os.Error) {
// Create TSIG and add it to the message.
q := new(Msg)
if !q.Unpack(msg) {
return nil, &Error{Error: "Failed to unpack"}
return nil, ErrUnpack
}
rr := new(RR_TSIG)
@ -116,7 +116,7 @@ func (t *Tsig) Generate(msg []byte) ([]byte, os.Error) {
q.Extra = append(q.Extra, rr)
send, ok := q.Pack()
if !ok {
return send, &Error{Error: "Failed to pack"}
return send, ErrPack
}
return send, nil
}
@ -132,7 +132,7 @@ func (t *Tsig) Verify(msg []byte) (bool, os.Error) {
// Stipped the TSIG from the incoming msg
stripped, ok := stripTsig(msg)
if !ok {
return false, &Error{Error: "Failed to strip tsig"}
return false, ErrSigGen
}
buf, err := t.Buffer(stripped)
@ -162,7 +162,7 @@ func (t *Tsig) Buffer(msg []byte) ([]byte, os.Error) {
macbuf = make([]byte, len(t.RequestMAC)) // reqmac should be twice as long
n, ok := packStruct(m, macbuf, 0)
if !ok {
return nil, &Error{Error: "Failed to pack request mac"}
return nil, ErrSigGen
}
macbuf = macbuf[:n]
}
@ -174,7 +174,7 @@ func (t *Tsig) Buffer(msg []byte) ([]byte, os.Error) {
tsig.Fudge = t.Fudge
n, ok1 := packStruct(tsig, tsigvar, 0)
if !ok1 {
return nil, &Error{Error: "Failed to pack timers"}
return nil, ErrSigGen
}
tsigvar = tsigvar[:n]
} else {
@ -190,7 +190,7 @@ func (t *Tsig) Buffer(msg []byte) ([]byte, os.Error) {
tsig.OtherData = ""
n, ok1 := packStruct(tsig, tsigvar, 0)
if !ok1 {
return nil, &Error{Error: "Failed to pack tsig variables"}
return nil, ErrSigGen
}
tsigvar = tsigvar[:n]
}

View File

@ -61,7 +61,7 @@ const (
TypeTKEY = 249
TypeTSIG = 250
// valid Question.qtype only
// valid Question.Qtype only
TypeIXFR = 251
TypeAXFR = 252
TypeMAILB = 253
@ -73,7 +73,7 @@ const (
TypeTA = 32768
TypeDLV = 32769
// valid Question.qclass
// valid Question.Qclass
ClassINET = 1
ClassCSNET = 2
ClassCHAOS = 3

12
xfr.go
View File

@ -35,7 +35,7 @@ func (d *Conn) XfrRead(q *Msg, m chan Xfr) {
case TypeIXFR:
d.ixfrRead(q, m)
default:
m <- Xfr{true, nil, &Error{Error: "Qtype not recognized"}}
m <- Xfr{true, nil, &Error{Error: "Xfr Qtype not recognized"}}
close(m)
}
}
@ -51,7 +51,7 @@ func (d *Conn) XfrWrite(q *Msg, m chan Xfr) {
case TypeIXFR:
// d.ixfrWrite(q, m)
default:
m <- Xfr{true, nil, &Error{Error: "Qtype not recognized"}}
m <- Xfr{true, nil, &Error{Error: "Xfr Qtype not recognized"}}
close(m)
}
}
@ -67,13 +67,13 @@ func (d *Conn) axfrRead(q *Msg, m chan Xfr) {
return
}
if in.Id != q.Id {
m <- Xfr{true, nil, &Error{Error: "Id mismatch"}}
m <- Xfr{true, nil, ErrId}
return
}
if first {
if !checkXfrSOA(in, true) {
m <- Xfr{true, nil, &Error{Error: "SOA not first record"}}
m <- Xfr{true, nil, ErrXfrSoa}
return
}
first = !first
@ -152,7 +152,7 @@ func (d *Conn) ixfrRead(q *Msg, m chan Xfr) {
return
}
if in.Id != q.Id {
m <- Xfr{true, nil, &Error{Error: "Id mismatch"}}
m <- Xfr{true, nil, ErrId}
return
}
@ -164,7 +164,7 @@ func (d *Conn) ixfrRead(q *Msg, m chan Xfr) {
// But still check if the returned answer is ok
if !checkXfrSOA(in, true) {
m <- Xfr{true, nil, &Error{Error: "SOA not first record"}}
m <- Xfr{true, nil, ErrXfrSoa}
return
}
// This serial is important