From 8aa88a0bd318da123f540128281b468ac26ebecf Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Fri, 25 Mar 2011 11:19:35 +0100 Subject: [PATCH] normalize errors --- dns.go | 30 +++++++++++++++--------------- edns.go | 2 +- keygen.go | 14 +++++++------- msg.go | 15 +++++++++++++++ resolver.go | 10 +--------- tsig.go | 12 ++++++------ types.go | 4 ++-- xfr.go | 12 ++++++------ 8 files changed, 53 insertions(+), 46 deletions(-) diff --git a/dns.go b/dns.go index a32e8c41..c09d3ee6 100644 --- a/dns.go +++ b/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 { diff --git a/edns.go b/edns.go index fd62021f..b56bd351 100644 --- a/edns.go +++ b/edns.go @@ -5,7 +5,7 @@ import ( "encoding/hex" ) -// EDNS0 Options +// EDNS0 Option codes. const ( _ = iota OptionCodeLLQ // not used diff --git a/keygen.go b/keygen.go index ef1486a0..4afbe443 100644 --- a/keygen.go +++ b/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 } diff --git a/msg.go b/msg.go index 0f589306..13e94393 100644 --- a/msg.go +++ b/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 { diff --git a/resolver.go b/resolver.go index 830f5e40..b7c0ea42 100644 --- a/resolver.go +++ b/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) diff --git a/tsig.go b/tsig.go index 60800f2c..958d14e8 100644 --- a/tsig.go +++ b/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] } diff --git a/types.go b/types.go index cdf3b620..d74cc12a 100644 --- a/types.go +++ b/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 diff --git a/xfr.go b/xfr.go index 12322489..f61e99d7 100644 --- a/xfr.go +++ b/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