Fixes the latest weekly

This commit is contained in:
Miek Gieben 2011-11-02 23:06:54 +01:00
parent f00b7ec494
commit 22a467e718
14 changed files with 6209 additions and 6234 deletions

View File

@ -4,7 +4,6 @@ package main
import ( import (
"dns" "dns"
"fmt" "fmt"
"os"
"strconv" "strconv"
"strings" "strings"
) )
@ -64,7 +63,7 @@ func sendProbe(c *dns.Client, addr string, f *fingerprint, q dns.Question) *fing
// This leads to strings like: "QUERY,NOERROR,qr,aa,tc,RD,ad,cd,z,1,0,0,1,DO,4096,NSID" // This leads to strings like: "QUERY,NOERROR,qr,aa,tc,RD,ad,cd,z,1,0,0,1,DO,4096,NSID"
type fingerprint struct { type fingerprint struct {
Error os.Error Error error
Opcode int Opcode int
Rcode int Rcode int
Response bool Response bool
@ -81,7 +80,7 @@ type fingerprint struct {
Extra int Extra int
Do bool Do bool
UDPSize int UDPSize int
Nsid bool Nsid bool
} }
// String creates a (short) string representation of a dns message. // String creates a (short) string representation of a dns message.
@ -187,10 +186,10 @@ func (f *fingerprint) error() string {
if f.Error == nil { if f.Error == nil {
panic("error is nil") panic("error is nil")
} }
return f.Error.String() return f.Error.Error()
} }
func errorToFingerprint(e os.Error) *fingerprint { func errorToFingerprint(e error) *fingerprint {
f := new(fingerprint) f := new(fingerprint)
f.Error = e f.Error = e
return f return f
@ -226,10 +225,10 @@ func msgToFingerprint(m *dns.Msg) *fingerprint {
// version is always 0 - and I cannot set it anyway // version is always 0 - and I cannot set it anyway
f.Do = r.(*dns.RR_OPT).Do() f.Do = r.(*dns.RR_OPT).Do()
f.UDPSize = int(r.(*dns.RR_OPT).UDPSize()) f.UDPSize = int(r.(*dns.RR_OPT).UDPSize())
if len(r.(*dns.RR_OPT).Option) == 1 { if len(r.(*dns.RR_OPT).Option) == 1 {
// Only support NSID atm // Only support NSID atm
f.Nsid = r.(*dns.RR_OPT).Option[0].Code == dns.OptionCodeNSID f.Nsid = r.(*dns.RR_OPT).Option[0].Code == dns.OptionCodeNSID
} }
} }
} }
return f return f
@ -258,9 +257,9 @@ func (f *fingerprint) toProbe(q dns.Question) *dns.Msg {
m.SetEdns0(0, true) m.SetEdns0(0, true)
// We have added an OPT RR, set the size. // We have added an OPT RR, set the size.
m.Extra[0].(*dns.RR_OPT).SetUDPSize(uint16(f.UDPSize)) m.Extra[0].(*dns.RR_OPT).SetUDPSize(uint16(f.UDPSize))
if f.Nsid { if f.Nsid {
m.Extra[0].(*dns.RR_OPT).SetNsid("") m.Extra[0].(*dns.RR_OPT).SetNsid("")
} }
} }
return m return m
} }

View File

@ -8,7 +8,6 @@ package dns
// when the query returns. // when the query returns.
import ( import (
"os"
"io" "io"
"net" "net"
) )
@ -22,10 +21,10 @@ type QueryHandler interface {
// construct a DNS request. // construct a DNS request.
type RequestWriter interface { type RequestWriter interface {
Write(*Msg) Write(*Msg)
Send(*Msg) os.Error Send(*Msg) error
Receive() (*Msg, os.Error) Receive() (*Msg, error)
Close() os.Error Close() error
Dial() os.Error Dial() error
} }
// hijacked connections...? // hijacked connections...?
@ -124,8 +123,8 @@ type Client struct {
Net string // if "tcp" a TCP query will be initiated, otherwise an UDP one Net string // if "tcp" a TCP query will be initiated, otherwise an UDP one
Attempts int // number of attempts Attempts int // number of attempts
Retry bool // retry with TCP Retry bool // retry with TCP
QueryChan chan *Request // read DNS request from this channel QueryChan chan *Request // read DNS request from this channel
ReplyChan chan *Exchange // write the reply (together with the DNS request) to this channel ReplyChan chan *Exchange // write the reply (together with the DNS request) to this channel
ReadTimeout int64 // the net.Conn.SetReadTimeout value for new connections (ns) ReadTimeout int64 // the net.Conn.SetReadTimeout value for new connections (ns)
WriteTimeout int64 // the net.Conn.SetWriteTimeout value for new connections (ns) WriteTimeout int64 // the net.Conn.SetWriteTimeout value for new connections (ns)
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret> TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>
@ -140,8 +139,8 @@ func NewClient() *Client {
c := new(Client) c := new(Client)
c.Net = "udp" c.Net = "udp"
c.Attempts = 1 c.Attempts = 1
c.ReplyChan = DefaultReplyChan c.ReplyChan = DefaultReplyChan
c.QueryChan = DefaultQueryChan c.QueryChan = DefaultQueryChan
c.ReadTimeout = 1 * 1e9 c.ReadTimeout = 1 * 1e9
c.WriteTimeout = 1 * 1e9 c.WriteTimeout = 1 * 1e9
return c return c
@ -149,10 +148,10 @@ func NewClient() *Client {
type Query struct { type Query struct {
QueryChan chan *Request // read DNS request from this channel QueryChan chan *Request // read DNS request from this channel
Handler QueryHandler // handler to invoke, dns.DefaultQueryMux if nil Handler QueryHandler // handler to invoke, dns.DefaultQueryMux if nil
} }
func (q *Query) Query() os.Error { func (q *Query) Query() error {
handler := q.Handler handler := q.Handler
if handler == nil { if handler == nil {
handler = DefaultQueryMux handler = DefaultQueryMux
@ -171,7 +170,7 @@ func (q *Query) Query() os.Error {
return nil return nil
} }
func (q *Query) ListenAndQuery() os.Error { func (q *Query) ListenAndQuery() error {
if q.QueryChan == nil { if q.QueryChan == nil {
q.QueryChan = DefaultQueryChan q.QueryChan = DefaultQueryChan
} }
@ -195,12 +194,12 @@ func (w *reply) Write(m *Msg) {
// Do performs an asynchronous query. The result is returned on the // Do performs an asynchronous query. The result is returned on the
// QueryChan channel set in the Client c. // QueryChan channel set in the Client c.
func (c *Client) Do(m *Msg, a string) { func (c *Client) Do(m *Msg, a string) {
c.QueryChan <- &Request{Client: c, Addr: a, Request: m} c.QueryChan <- &Request{Client: c, Addr: a, Request: m}
} }
// ExchangeBuffer performs a synchronous query. It sends the buffer m to the // ExchangeBuffer performs a synchronous query. It sends the buffer m to the
// address (net.Addr?) contained in a // address (net.Addr?) contained in a
func (c *Client) ExchangeBuffer(inbuf []byte, a string, outbuf []byte) (n int, err os.Error) { func (c *Client) ExchangeBuffer(inbuf []byte, a string, outbuf []byte) (n int, err error) {
w := new(reply) w := new(reply)
w.client = c w.client = c
w.addr = a w.addr = a
@ -224,7 +223,7 @@ func (c *Client) ExchangeBuffer(inbuf []byte, a string, outbuf []byte) (n int, e
// Exchange performs an synchronous query. It sends the message m to the address // Exchange performs an synchronous query. It sends the message m to the address
// contained in a and waits for an reply. // contained in a and waits for an reply.
func (c *Client) Exchange(m *Msg, a string) (r *Msg, err os.Error) { func (c *Client) Exchange(m *Msg, a string) (r *Msg, err error) {
var n int var n int
out, ok := m.Pack() out, ok := m.Pack()
if !ok { if !ok {
@ -248,7 +247,7 @@ func (c *Client) Exchange(m *Msg, a string) (r *Msg, err os.Error) {
} }
// Dial connects to the address addr for the network set in c.Net // Dial connects to the address addr for the network set in c.Net
func (w *reply) Dial() os.Error { func (w *reply) Dial() error {
conn, err := net.Dial(w.Client().Net, w.addr) conn, err := net.Dial(w.Client().Net, w.addr)
if err != nil { if err != nil {
return err return err
@ -258,7 +257,7 @@ func (w *reply) Dial() os.Error {
} }
// UDP/TCP stuff big TODO // UDP/TCP stuff big TODO
func (w *reply) Close() (err os.Error) { func (w *reply) Close() (err error) {
return w.conn.Close() return w.conn.Close()
} }
@ -270,7 +269,7 @@ func (w *reply) Request() *Msg {
return w.req return w.req
} }
func (w *reply) Receive() (*Msg, os.Error) { func (w *reply) Receive() (*Msg, error) {
var p []byte var p []byte
m := new(Msg) m := new(Msg)
switch w.Client().Net { switch w.Client().Net {
@ -294,8 +293,8 @@ func (w *reply) Receive() (*Msg, os.Error) {
if !ok { if !ok {
return m, ErrSecret return m, ErrSecret
} }
// Need to work on the original message p, as that was used // Need to work on the original message p, as that was used
// to calculate the tsig. // to calculate the tsig.
err := TsigVerify(p, w.Client().TsigSecret[secret], w.tsigRequestMAC, w.tsigTimersOnly) err := TsigVerify(p, w.Client().TsigSecret[secret], w.tsigRequestMAC, w.tsigTimersOnly)
if err != nil { if err != nil {
return m, err return m, err
@ -304,9 +303,9 @@ func (w *reply) Receive() (*Msg, os.Error) {
return m, nil return m, nil
} }
func (w *reply) readClient(p []byte) (n int, err os.Error) { func (w *reply) readClient(p []byte) (n int, err error) {
if w.conn == nil { if w.conn == nil {
return 0, ErrConnEmpty return 0, ErrConnEmpty
//panic("no connection") //panic("no connection")
} }
switch w.Client().Net { switch w.Client().Net {
@ -350,16 +349,16 @@ func (w *reply) readClient(p []byte) (n int, err os.Error) {
// Send sends a dns msg to the address specified in w. // Send sends a dns msg to the address specified in w.
// If the message m contains a TSIG record the transaction // If the message m contains a TSIG record the transaction
// signature is calculated. // signature is calculated.
func (w *reply) Send(m *Msg) os.Error { func (w *reply) Send(m *Msg) error {
if m.IsTsig() { if m.IsTsig() {
secret := m.Extra[len(m.Extra)-1].(*RR_TSIG).Hdr.Name secret := m.Extra[len(m.Extra)-1].(*RR_TSIG).Hdr.Name
_, ok := w.Client().TsigSecret[secret] _, ok := w.Client().TsigSecret[secret]
if !ok { if !ok {
return ErrSecret return ErrSecret
} }
if err := TsigGenerate(m, w.Client().TsigSecret[secret], w.tsigRequestMAC, w.tsigTimersOnly); err != nil { if err := TsigGenerate(m, w.Client().TsigSecret[secret], w.tsigRequestMAC, w.tsigTimersOnly); err != nil {
return err return err
} }
w.tsigRequestMAC = m.Extra[len(m.Extra)-1].(*RR_TSIG).MAC // Save the requestMAC for the next packet w.tsigRequestMAC = m.Extra[len(m.Extra)-1].(*RR_TSIG).MAC // Save the requestMAC for the next packet
} }
out, ok := m.Pack() out, ok := m.Pack()
@ -373,7 +372,7 @@ func (w *reply) Send(m *Msg) os.Error {
return nil return nil
} }
func (w *reply) writeClient(p []byte) (n int, err os.Error) { func (w *reply) writeClient(p []byte) (n int, err error) {
if w.Client().Attempts == 0 { if w.Client().Attempts == 0 {
panic("c.Attempts 0") panic("c.Attempts 0")
} }
@ -384,8 +383,8 @@ func (w *reply) writeClient(p []byte) (n int, err os.Error) {
if err = w.Dial(); err != nil { if err = w.Dial(); err != nil {
return 0, err return 0, err
} }
w.conn.SetWriteTimeout(w.Client().WriteTimeout) w.conn.SetWriteTimeout(w.Client().WriteTimeout)
w.conn.SetReadTimeout(w.Client().ReadTimeout) w.conn.SetReadTimeout(w.Client().ReadTimeout)
} }
switch w.Client().Net { switch w.Client().Net {

View File

@ -28,7 +28,7 @@ type ClientConfig struct {
// See resolv.conf(5) on a Linux machine. // See resolv.conf(5) on a Linux machine.
// Parse a /etc/resolv.conf like file and return a filled out ClientConfig. Note // Parse a /etc/resolv.conf like file and return a filled out ClientConfig. Note
// that all nameservers will have the default port number appended (:53) // that all nameservers will have the default port number appended (:53)
func ClientConfigFromFile(conf string) (*ClientConfig, os.Error) { func ClientConfigFromFile(conf string) (*ClientConfig, error) {
file, err := os.Open(conf) file, err := os.Open(conf)
defer file.Close() defer file.Close()
if err != nil { if err != nil {

21
dns.go
View File

@ -52,7 +52,6 @@ package dns
import ( import (
"net" "net"
"os"
"strconv" "strconv"
) )
@ -65,17 +64,17 @@ const (
// Error represents a DNS error // Error represents a DNS error
type Error struct { type Error struct {
Error string Err string
Name string Name string
Server net.Addr Server net.Addr
Timeout bool Timeout bool
} }
func (e *Error) String() string { func (e *Error) Error() string {
if e == nil { if e == nil {
return "<nil>" return "<nil>"
} }
return e.Error return e.Err
} }
type RR interface { type RR interface {
@ -153,9 +152,9 @@ func (s RRset) Ok() bool {
// Exchange is used in communicating with the resolver. // Exchange is used in communicating with the resolver.
type Exchange struct { type Exchange struct {
Request *Msg // The question sent. Request *Msg // The question sent.
Reply *Msg // The answer to the question that was sent. Reply *Msg // The answer to the question that was sent.
Error os.Error // If something when wrong, this contains the error. Error error // If something when wrong, this contains the error.
} }
// DNS resource records. // DNS resource records.
@ -230,10 +229,10 @@ func zoneMatch(pattern, zone string) (ok bool) {
// DnameLength returns the length of a packed dname. // DnameLength returns the length of a packed dname.
func DomainNameLength(s string) int { // TODO better name func DomainNameLength(s string) int { // TODO better name
// Special case for '.' // Special case for '.'
if s == "." { if s == "." {
return 1 return 1
} }
// Add trailing dot to canonicalize name. // Add trailing dot to canonicalize name.
if n := len(s); n == 0 || s[n-1] != '.' { if n := len(s); n == 0 || s[n-1] != '.' {

View File

@ -18,7 +18,6 @@ import (
"big" "big"
"sort" "sort"
"strings" "strings"
"os"
) )
// DNSSEC encryption algorithm codes. // DNSSEC encryption algorithm codes.
@ -172,7 +171,7 @@ func (k *RR_DNSKEY) ToDS(h int) *RR_DS {
// otherwise false. // otherwise false.
// The signature data in the RRSIG is filled by this method. // The signature data in the RRSIG is filled by this method.
// There is no check if RRSet is a proper (RFC 2181) RRSet. // There is no check if RRSet is a proper (RFC 2181) RRSet.
func (s *RR_RRSIG) Sign(k PrivateKey, rrset RRset) os.Error { func (s *RR_RRSIG) Sign(k PrivateKey, rrset RRset) error {
if k == nil { if k == nil {
return ErrPrivKey return ErrPrivKey
} }
@ -263,7 +262,7 @@ func (s *RR_RRSIG) Sign(k PrivateKey, rrset RRset) os.Error {
// Verify validates an RRSet with the signature and key. This is only the // Verify validates an RRSet with the signature and key. This is only the
// cryptographic test, the signature validity period most be checked separately. // cryptographic test, the signature validity period most be checked separately.
func (s *RR_RRSIG) Verify(k *RR_DNSKEY, rrset RRset) os.Error { func (s *RR_RRSIG) Verify(k *RR_DNSKEY, rrset RRset) error {
// Frist the easy checks // Frist the easy checks
if s.KeyTag != k.KeyTag() { if s.KeyTag != k.KeyTag() {
return ErrKey return ErrKey
@ -337,7 +336,7 @@ func (s *RR_RRSIG) Verify(k *RR_DNSKEY, rrset RRset) os.Error {
return rsa.VerifyPKCS1v15(pubkey, ch, sighash, sigbuf) return rsa.VerifyPKCS1v15(pubkey, ch, sighash, sigbuf)
} }
// Unknown alg // Unknown alg
return ErrAlg return ErrAlg
} }
// ValidityPeriod uses RFC1982 serial arithmetic to calculate // ValidityPeriod uses RFC1982 serial arithmetic to calculate

View File

@ -1,7 +1,6 @@
package dns package dns
import ( import (
"os"
"io" "io"
"big" "big"
"strconv" "strconv"
@ -21,9 +20,9 @@ type PrivateKey interface{}
// what kind of DNSKEY will be generated. // what kind of DNSKEY will be generated.
// The ECDSA algorithms imply a fixed keysize, in that case // The ECDSA algorithms imply a fixed keysize, in that case
// bits should be set to the size of the algorithm. // bits should be set to the size of the algorithm.
func (r *RR_DNSKEY) Generate(bits int) (PrivateKey, os.Error) { func (r *RR_DNSKEY) Generate(bits int) (PrivateKey, error) {
switch r.Algorithm { switch r.Algorithm {
case RSAMD5, RSASHA1, RSASHA256, RSASHA1NSEC3SHA1: case RSAMD5, RSASHA1, RSASHA256, RSASHA1NSEC3SHA1:
if bits < 512 || bits > 4096 { if bits < 512 || bits > 4096 {
return nil, ErrKeySize return nil, ErrKeySize
} }
@ -42,7 +41,7 @@ func (r *RR_DNSKEY) Generate(bits int) (PrivateKey, os.Error) {
} }
switch r.Algorithm { switch r.Algorithm {
case RSAMD5, RSASHA1, RSASHA256, RSASHA512, RSASHA1NSEC3SHA1: case RSAMD5, RSASHA1, RSASHA256, RSASHA512, RSASHA1NSEC3SHA1:
priv, err := rsa.GenerateKey(rand.Reader, bits) priv, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil { if err != nil {
return nil, err return nil, err
@ -113,7 +112,7 @@ func (r *RR_DNSKEY) PrivateKeyString(p PrivateKey) (s string) {
} }
// Read reads a DNSKEY from the io.Reader q. // Read reads a DNSKEY from the io.Reader q.
func (k *RR_DNSKEY) Read(q io.Reader) os.Error { func (k *RR_DNSKEY) Read(q io.Reader) error {
p := NewParser(q) p := NewParser(q)
r, err := p.First() r, err := p.First()
if err != nil { if err != nil {
@ -131,12 +130,12 @@ func (k *RR_DNSKEY) Read(q io.Reader) os.Error {
} }
// ReadPrivateKey reads a private key from the io.Reader q. // ReadPrivateKey reads a private key from the io.Reader q.
func (k *RR_DNSKEY) ReadPrivateKey(q io.Reader) (PrivateKey, os.Error) { func (k *RR_DNSKEY) ReadPrivateKey(q io.Reader) (PrivateKey, error) {
p := NewParser(q) p := NewParser(q)
kv, _ := p.PrivateKey() kv, _ := p.PrivateKey()
if kv == nil { if kv == nil {
return nil, ErrPrivKey return nil, ErrPrivKey
} }
if _, ok := kv["private-key-format"]; !ok { if _, ok := kv["private-key-format"]; !ok {
return nil, ErrPrivKey return nil, ErrPrivKey
} }
@ -153,7 +152,7 @@ func (k *RR_DNSKEY) ReadPrivateKey(q io.Reader) (PrivateKey, os.Error) {
} }
// Read a private key (file) string and create a public key. Return the private key. // Read a private key (file) string and create a public key. Return the private key.
func (k *RR_DNSKEY) readPrivateKeyRSA(kv map[string]string) (PrivateKey, os.Error) { func (k *RR_DNSKEY) readPrivateKeyRSA(kv map[string]string) (PrivateKey, error) {
p := new(rsa.PrivateKey) p := new(rsa.PrivateKey)
p.Primes = []*big.Int{nil, nil} p.Primes = []*big.Int{nil, nil}
for k, v := range kv { for k, v := range kv {
@ -190,7 +189,7 @@ func (k *RR_DNSKEY) readPrivateKeyRSA(kv map[string]string) (PrivateKey, os.Erro
return p, nil return p, nil
} }
func (k *RR_DNSKEY) readPrivateKeyECDSA(kv map[string]string) (PrivateKey, os.Error) { func (k *RR_DNSKEY) readPrivateKeyECDSA(kv map[string]string) (PrivateKey, error) {
p := new(ecdsa.PrivateKey) p := new(ecdsa.PrivateKey)
p.D = big.NewInt(0) p.D = big.NewInt(0)
// Need to check if we have everything // Need to check if we have everything

4808
kparse.go

File diff suppressed because it is too large Load Diff

59
msg.go
View File

@ -15,7 +15,6 @@
package dns package dns
import ( import (
"os"
"reflect" "reflect"
"net" "net"
"rand" "rand"
@ -27,31 +26,31 @@ import (
) )
var ( var (
ErrUnpack os.Error = &Error{Error: "unpacking failed"} ErrUnpack error = &Error{Err: "unpacking failed"}
ErrPack os.Error = &Error{Error: "packing failed"} ErrPack error = &Error{Err: "packing failed"}
ErrId os.Error = &Error{Error: "id mismatch"} ErrId error = &Error{Err: "id mismatch"}
ErrShortRead os.Error = &Error{Error: "short read"} ErrShortRead error = &Error{Err: "short read"}
ErrConn os.Error = &Error{Error: "conn holds both UDP and TCP connection"} ErrConn error = &Error{Err: "conn holds both UDP and TCP connection"}
ErrConnEmpty os.Error = &Error{Error: "conn has no connection"} ErrConnEmpty error = &Error{Err: "conn has no connection"}
ErrServ os.Error = &Error{Error: "no servers could be reached"} ErrServ error = &Error{Err: "no servers could be reached"}
ErrKey os.Error = &Error{Error: "bad key"} ErrKey error = &Error{Err: "bad key"}
ErrPrivKey os.Error = &Error{Error: "bad private key"} ErrPrivKey error = &Error{Err: "bad private key"}
ErrKeySize os.Error = &Error{Error: "bad key size"} ErrKeySize error = &Error{Err: "bad key size"}
ErrKeyAlg os.Error = &Error{Error: "bad key algorithm"} ErrKeyAlg error = &Error{Err: "bad key algorithm"}
ErrAlg os.Error = &Error{Error: "bad algorithm"} ErrAlg error = &Error{Err: "bad algorithm"}
ErrTime os.Error = &Error{Error: "bad time"} ErrTime error = &Error{Err: "bad time"}
ErrNoSig os.Error = &Error{Error: "no signature found"} ErrNoSig error = &Error{Err: "no signature found"}
ErrSig os.Error = &Error{Error: "bad signature"} ErrSig error = &Error{Err: "bad signature"}
ErrSecret os.Error = &Error{Error: "no secret defined"} ErrSecret error = &Error{Err: "no secret defined"}
ErrSigGen os.Error = &Error{Error: "bad signature generation"} ErrSigGen error = &Error{Err: "bad signature generation"}
ErrAuth os.Error = &Error{Error: "bad authentication"} ErrAuth error = &Error{Err: "bad authentication"}
ErrXfrSoa os.Error = &Error{Error: "no SOA seen"} ErrXfrSoa error = &Error{Err: "no SOA seen"}
ErrXfrLast os.Error = &Error{Error: "last SOA"} ErrXfrLast error = &Error{Err: "last SOA"}
ErrXfrType os.Error = &Error{Error: "no ixfr, nor axfr"} ErrXfrType error = &Error{Err: "no ixfr, nor axfr"}
ErrHandle os.Error = &Error{Error: "handle is nil"} ErrHandle error = &Error{Err: "handle is nil"}
ErrChan os.Error = &Error{Error: "channel is nil"} ErrChan error = &Error{Err: "channel is nil"}
ErrName os.Error = &Error{Error: "type not found for name"} ErrName error = &Error{Err: "type not found for name"}
ErrRRset os.Error = &Error{Error: "invalid rrset"} ErrRRset error = &Error{Err: "invalid rrset"}
) )
// A manually-unpacked version of (id, bits). // A manually-unpacked version of (id, bits).
@ -317,7 +316,7 @@ func packStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok bool)
//fmt.Fprintf(os.Stderr, "dns: unknown packing slice tag %v\n", f.Tag) //fmt.Fprintf(os.Stderr, "dns: unknown packing slice tag %v\n", f.Tag)
return lenmsg, false return lenmsg, false
case "OPT": // edns case "OPT": // edns
// Length of the entire option section // Length of the entire option section
for j := 0; j < val.Field(i).Len(); j++ { for j := 0; j < val.Field(i).Len(); j++ {
element := val.Field(i).Index(j) element := val.Field(i).Index(j)
// for each code we should do something else // for each code we should do something else
@ -330,7 +329,7 @@ func packStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok bool)
msg[off], msg[off+1] = packUint16(code) msg[off], msg[off+1] = packUint16(code)
// Length // Length
msg[off+2], msg[off+3] = packUint16(uint16(len(string(h)))) msg[off+2], msg[off+3] = packUint16(uint16(len(string(h))))
off += 4 off += 4
copy(msg[off:off+len(string(h))], h) copy(msg[off:off+len(string(h))], h)
off += len(string(h)) off += len(string(h))
@ -793,7 +792,7 @@ func packUint16(i uint16) (byte, byte) {
return byte(i >> 8), byte(i) return byte(i >> 8), byte(i)
} }
func packBase64(s []byte) ([]byte, os.Error) { func packBase64(s []byte) ([]byte, error) {
b64len := base64.StdEncoding.DecodedLen(len(s)) b64len := base64.StdEncoding.DecodedLen(len(s))
buf := make([]byte, b64len) buf := make([]byte, b64len)
n, err := base64.StdEncoding.Decode(buf, []byte(s)) n, err := base64.StdEncoding.Decode(buf, []byte(s))
@ -805,7 +804,7 @@ func packBase64(s []byte) ([]byte, os.Error) {
} }
// Helper function for packing, mostly used in dnssec.go // Helper function for packing, mostly used in dnssec.go
func packBase32(s []byte) ([]byte, os.Error) { func packBase32(s []byte) ([]byte, error) {
b32len := base32.HexEncoding.DecodedLen(len(s)) b32len := base32.HexEncoding.DecodedLen(len(s))
buf := make([]byte, b32len) buf := make([]byte, b32len)
n, err := base32.HexEncoding.Decode(buf, []byte(s)) n, err := base32.HexEncoding.Decode(buf, []byte(s))

View File

@ -5,7 +5,6 @@ import (
"hash" "hash"
"strings" "strings"
"crypto/sha1" "crypto/sha1"
"os"
) )
type saltWireFmt struct { type saltWireFmt struct {
@ -63,13 +62,13 @@ func (nsec3 *RR_NSEC3) HashNames() {
// the message m. // the message m.
// NsecVerify returns nil when the NSECs in the message contain // NsecVerify returns nil when the NSECs in the message contain
// the correct proof. This function does not validates the NSECs // the correct proof. This function does not validates the NSECs
func (m *Msg) NsecVerify(q Question) os.Error { func (m *Msg) NsecVerify(q Question) error {
return nil return nil
} }
// Nsec3Verify verifies ... // Nsec3Verify verifies ...
func (m *Msg) Nsec3Verify(q Question) os.Error { func (m *Msg) Nsec3Verify(q Question) error {
return nil return nil
} }

View File

@ -8,7 +8,6 @@ package dns
import ( import (
"io" "io"
"os"
"net" "net"
) )
@ -26,7 +25,7 @@ type ResponseWriter interface {
// RemoteAddr returns the net.Addr of the client that sent the current request. // RemoteAddr returns the net.Addr of the client that sent the current request.
RemoteAddr() net.Addr RemoteAddr() net.Addr
// Write a reply back to the client. // Write a reply back to the client.
Write([]byte) (int, os.Error) Write([]byte) (int, error)
} }
// port? // port?
@ -73,8 +72,8 @@ func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg) {
// RCODE = refused for every request. // RCODE = refused for every request.
func Refused(w ResponseWriter, r *Msg) { func Refused(w ResponseWriter, r *Msg) {
m := new(Msg) m := new(Msg)
m.SetRcode(r, RcodeRefused) m.SetRcode(r, RcodeRefused)
buf, _ := m.Pack() buf, _ := m.Pack()
w.Write(buf) w.Write(buf)
} }
@ -82,7 +81,7 @@ func Refused(w ResponseWriter, r *Msg) {
func RefusedHandler() Handler { return HandlerFunc(Refused) } func RefusedHandler() Handler { return HandlerFunc(Refused) }
// ... // ...
func ListenAndServe(addr string, network string, handler Handler) os.Error { func ListenAndServe(addr string, network string, handler Handler) error {
server := &Server{Addr: addr, Net: network, Handler: handler} server := &Server{Addr: addr, Net: network, Handler: handler}
return server.ListenAndServe() return server.ListenAndServe()
} }
@ -148,7 +147,7 @@ type Server struct {
} }
// ... // ...
func (srv *Server) ListenAndServe() os.Error { func (srv *Server) ListenAndServe() error {
addr := srv.Addr addr := srv.Addr
if addr == "" { if addr == "" {
addr = ":domain" addr = ":domain"
@ -178,7 +177,7 @@ func (srv *Server) ListenAndServe() os.Error {
return nil // os.Error with wrong network return nil // os.Error with wrong network
} }
func (srv *Server) ServeTCP(l *net.TCPListener) os.Error { func (srv *Server) ServeTCP(l *net.TCPListener) error {
defer l.Close() defer l.Close()
handler := srv.Handler handler := srv.Handler
if handler == nil { if handler == nil {
@ -228,7 +227,7 @@ forever:
panic("not reached") panic("not reached")
} }
func (srv *Server) ServeUDP(l *net.UDPConn) os.Error { func (srv *Server) ServeUDP(l *net.UDPConn) error {
defer l.Close() defer l.Close()
handler := srv.Handler handler := srv.Handler
if handler == nil { if handler == nil {
@ -257,7 +256,7 @@ func (srv *Server) ServeUDP(l *net.UDPConn) os.Error {
panic("not reached") panic("not reached")
} }
func newConn(t *net.TCPConn, u *net.UDPConn, a net.Addr, buf []byte, handler Handler) (*conn, os.Error) { func newConn(t *net.TCPConn, u *net.UDPConn, a net.Addr, buf []byte, handler Handler) (*conn, error) {
c := new(conn) c := new(conn)
c.handler = handler c.handler = handler
c._TCP = t c._TCP = t
@ -267,7 +266,6 @@ func newConn(t *net.TCPConn, u *net.UDPConn, a net.Addr, buf []byte, handler Han
return c, nil return c, nil
} }
// Close the connection. // Close the connection.
func (c *conn) close() { func (c *conn) close() {
switch { switch {
@ -288,11 +286,11 @@ func (c *conn) serve() {
w.conn = c w.conn = c
req := new(Msg) req := new(Msg)
if !req.Unpack(c.request) { if !req.Unpack(c.request) {
// Send a format error back // Send a format error back
x := new(Msg) x := new(Msg)
x.SetRcodeFormatError(req) x.SetRcodeFormatError(req)
buf, _ := x.Pack() buf, _ := x.Pack()
w.Write(buf) w.Write(buf)
break break
} }
w.req = req w.req = req
@ -307,13 +305,12 @@ func (c *conn) serve() {
} }
} }
func (w *response) Write(data []byte) (n int, err error) {
func (w *response) Write(data []byte) (n int, err os.Error) {
switch { switch {
case w.conn._UDP != nil: case w.conn._UDP != nil:
n, err = w.conn._UDP.WriteTo(data, w.conn.remoteAddr) n, err = w.conn._UDP.WriteTo(data, w.conn.remoteAddr)
if err != nil { if err != nil {
println(err.String()) println(err.Error())
return 0, err return 0, err
} }
case w.conn._TCP != nil: case w.conn._TCP != nil:

35
tsig.go
View File

@ -34,7 +34,6 @@ package dns
import ( import (
"io" "io"
"os"
"time" "time"
"strings" "strings"
"crypto/hmac" "crypto/hmac"
@ -82,16 +81,16 @@ type timerWireFmt struct {
// in the Tsig RR that is added. When TsigGenerate is called for the // in the Tsig RR that is added. When TsigGenerate is called for the
// first time requestMAC is set to the empty string. // first time requestMAC is set to the empty string.
// If something goes wrong an error is returned, otherwise it is nil. // If something goes wrong an error is returned, otherwise it is nil.
func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) os.Error { func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) error {
if !m.IsTsig() { if !m.IsTsig() {
// panic? panic? // panic? panic?
panic("TSIG not last RR in additional") panic("TSIG not last RR in additional")
} }
// If we barf here, the caller is to blame // If we barf here, the caller is to blame
rawsecret, err := packBase64([]byte(secret)) rawsecret, err := packBase64([]byte(secret))
if err != nil { if err != nil {
return err return err
} }
rr := m.Extra[len(m.Extra)-1].(*RR_TSIG) rr := m.Extra[len(m.Extra)-1].(*RR_TSIG)
m.Extra = m.Extra[0 : len(m.Extra)-1] // kill the TSIG from the msg m.Extra = m.Extra[0 : len(m.Extra)-1] // kill the TSIG from the msg
@ -119,7 +118,7 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) os.Error {
// TsigVerify verifies the TSIG on a message. // TsigVerify verifies the TSIG on a message.
// If the signature does not validate err contains the // If the signature does not validate err contains the
// error, otherwise it is nil. // error, otherwise it is nil.
func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) os.Error { func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
rawsecret, err := packBase64([]byte(secret)) rawsecret, err := packBase64([]byte(secret))
if err != nil { if err != nil {
return err return err
@ -132,17 +131,17 @@ func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) os.Error
buf := tsigBuffer(stripped, tsig, requestMAC, timersOnly) buf := tsigBuffer(stripped, tsig, requestMAC, timersOnly)
ti := uint64(time.Seconds()) - tsig.TimeSigned ti := uint64(time.Seconds()) - tsig.TimeSigned
if uint64(tsig.Fudge) < ti { if uint64(tsig.Fudge) < ti {
return ErrTime return ErrTime
} }
h := hmac.NewMD5([]byte(rawsecret)) h := hmac.NewMD5([]byte(rawsecret))
io.WriteString(h, string(buf)) io.WriteString(h, string(buf))
if (strings.ToUpper(hex.EncodeToString(h.Sum())) != strings.ToUpper(tsig.MAC)) { if strings.ToUpper(hex.EncodeToString(h.Sum())) != strings.ToUpper(tsig.MAC) {
return ErrSig return ErrSig
} }
return nil return nil
} }
// Create a wiredata buffer for the MAC calculation. // Create a wiredata buffer for the MAC calculation.
@ -155,7 +154,7 @@ func tsigBuffer(msgbuf []byte, rr *RR_TSIG, requestMAC string, timersOnly bool)
rr.TimeSigned = uint64(time.Seconds()) rr.TimeSigned = uint64(time.Seconds())
} }
if rr.Fudge == 0 { if rr.Fudge == 0 {
rr.Fudge = 300 // Standard (RFC) default. rr.Fudge = 300 // Standard (RFC) default.
} }
if requestMAC != "" { if requestMAC != "" {
@ -198,7 +197,7 @@ func tsigBuffer(msgbuf []byte, rr *RR_TSIG, requestMAC string, timersOnly bool)
} }
// Strip the TSIG from the raw message // Strip the TSIG from the raw message
func stripTsig(msg []byte) ([]byte, *RR_TSIG, os.Error) { func stripTsig(msg []byte) ([]byte, *RR_TSIG, error) {
// Copied from msg.go's Unpack() // Copied from msg.go's Unpack()
// Header. // Header.
var dh Header var dh Header

View File

@ -6,7 +6,6 @@
package dns package dns
import ( import (
"os"
"net" "net"
"time" "time"
"strconv" "strconv"
@ -148,7 +147,7 @@ func (q *Question) String() string {
} }
// NewRRString returns the last RR contained in s. // NewRRString returns the last RR contained in s.
func NewRRString(s string) (RR, os.Error) { func NewRRString(s string) (RR, error) {
p := NewParser(strings.NewReader(s)) p := NewParser(strings.NewReader(s))
return p.First() return p.First()
} }
@ -162,8 +161,8 @@ func NewRR(i uint16) RR {
} }
type RR_ANY struct { type RR_ANY struct {
Hdr RR_Header Hdr RR_Header
// Does not have any rdata // Does not have any rdata
} }
func (rr *RR_ANY) Header() *RR_Header { func (rr *RR_ANY) Header() *RR_Header {
@ -792,7 +791,7 @@ func (rr *RR_TSIG) String() string {
" " + strconv.Itoa(int(rr.MACSize)) + " " + strconv.Itoa(int(rr.MACSize)) +
" " + strings.ToUpper(rr.MAC) + " " + strings.ToUpper(rr.MAC) +
" " + strconv.Itoa(int(rr.OrigId)) + " " + strconv.Itoa(int(rr.OrigId)) +
" " + strconv.Itoa(int(rr.Error)) + // BIND prints NOERROR " " + strconv.Itoa(int(rr.Error)) + // BIND prints NOERROR
" " + strconv.Itoa(int(rr.OtherLen)) + " " + strconv.Itoa(int(rr.OtherLen)) +
" " + rr.OtherData " " + rr.OtherData
} }

12
xfr.go
View File

@ -1,15 +1,11 @@
package dns package dns
import (
"os"
)
// XfrReceives requests an incoming Ixfr or Axfr. If the message q's question // XfrReceives requests an incoming Ixfr or Axfr. If the message q's question
// section contains an AXFR type an Axfr is performed, if it is IXFR it does an Ixfr. // section contains an AXFR type an Axfr is performed, if it is IXFR it does an Ixfr.
// Each message will be send along the Client's reply channel as it is received. // Each message will be send along the Client's reply channel as it is received.
// The last message send has Exchange.Error set to ErrXfrLast // The last message send has Exchange.Error set to ErrXfrLast
// to signal there is nothing more to come. // to signal there is nothing more to come.
func (c *Client) XfrReceive(q *Msg, a string) os.Error { func (c *Client) XfrReceive(q *Msg, a string) error {
w := new(reply) w := new(reply)
w.client = c w.client = c
w.addr = a w.addr = a
@ -117,10 +113,10 @@ func (w *reply) ixfrReceive() {
// XfrSend performs an outgoing Ixfr or Axfr. The function is xfr agnostic, it is // XfrSend performs an outgoing Ixfr or Axfr. The function is xfr agnostic, it is
// up to the caller to correctly send the sequence of messages. // up to the caller to correctly send the sequence of messages.
func XfrSend(w ResponseWriter, q *Msg, a string) os.Error { func XfrSend(w ResponseWriter, q *Msg, a string) error {
switch q.Question[0].Qtype { switch q.Question[0].Qtype {
case TypeAXFR, TypeIXFR: case TypeAXFR, TypeIXFR:
// go d.xfrWrite(q, m, e) // go d.xfrWrite(q, m, e)
default: default:
return ErrXfrType return ErrXfrType
} }

7347
zparse.go

File diff suppressed because it is too large Load Diff