normalize errors
This commit is contained in:
parent
9ac4df6b1d
commit
8aa88a0bd3
30
dns.go
30
dns.go
|
@ -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 {
|
||||
|
|
2
edns.go
2
edns.go
|
@ -5,7 +5,7 @@ import (
|
|||
"encoding/hex"
|
||||
)
|
||||
|
||||
// EDNS0 Options
|
||||
// EDNS0 Option codes.
|
||||
const (
|
||||
_ = iota
|
||||
OptionCodeLLQ // not used
|
||||
|
|
14
keygen.go
14
keygen.go
|
@ -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
15
msg.go
|
@ -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 {
|
||||
|
|
10
resolver.go
10
resolver.go
|
@ -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
12
tsig.go
|
@ -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]
|
||||
}
|
||||
|
|
4
types.go
4
types.go
|
@ -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
12
xfr.go
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue