From 78edd83ca61610699388cf74ba20f72b248ee007 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sun, 2 Dec 2012 08:13:57 +0100 Subject: [PATCH 1/7] Add comma --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 22cce1e1..468a8176 100644 --- a/README.markdown +++ b/README.markdown @@ -41,7 +41,7 @@ Miek Gieben - 2010-2012 - miek@miek.nl # Building Building is done with the `go` tool. If you have setup your GOPATH -correctly the following should work: +correctly, the following should work: go get github.com/miekg/dns go build dns From a014286039403b95ffddc2056bb6f7044a1f5aff Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sun, 2 Dec 2012 08:31:56 +0100 Subject: [PATCH 2/7] Some updates in the comments/documentation --- zscan.go | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/zscan.go b/zscan.go index 8be44002..543b5cbb 100644 --- a/zscan.go +++ b/zscan.go @@ -8,19 +8,16 @@ import ( "strings" ) -// Only used when debugging the parser itself. -var _DEBUG = false +var _DEBUG = false // Only used when debugging the parser itself. -// Complete unsure about the correctness of this value? -// Large blobs of base64 code might get longer than this.... -const maxTok = 2048 +const maxTok = 2048 // Largest token we can return. // Tokinize a RFC 1035 zone file. The tokenizer will normalize it: // * Add ownernames if they are left blank; // * Suppress sequences of spaces; -// * Make each RR fit on one line (NEWLINE is send as last) +// * Make each RR fit on one line (_NEWLINE is send as last) // * Handle comments: ; -// * Handle braces. +// * Handle braces - anywhere. const ( // Zonefile _EOF = iota @@ -44,7 +41,7 @@ const ( _EXPECT_OWNER_BL // Whitespace after the ownername _EXPECT_ANY // Expect rrtype, ttl or class _EXPECT_ANY_NOCLASS // Expect rrtype or ttl - _EXPECT_ANY_NOCLASS_BL // The Whitespace after _EXPECT_ANY_NOCLASS + _EXPECT_ANY_NOCLASS_BL // The whitespace after _EXPECT_ANY_NOCLASS _EXPECT_ANY_NOTTL // Expect rrtype or class _EXPECT_ANY_NOTTL_BL // Whitespace after _EXPECT_ANY_NOTTL _EXPECT_RRTYPE // Expect rrtype @@ -78,12 +75,12 @@ func (e *ParseError) Error() (s string) { } type lex struct { - token string // Text of the token - err bool // When true, token text has lexer error - value uint8 // Value: _STRING, _BLANK, etc. - line int // Line in the file - column int // Column in the file - torc uint16 // Type or class as parsed in the lexer, we only need to look this up in the grammar + token string // text of the token + err bool // when true, token text has lexer error + value uint8 // value: _STRING, _BLANK, etc. + line int // line in the file + column int // column in the file + torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar } // Tokens are returned when a zone file is parsed. From 77c679fe65d1bc36f5fb675ae7078600c74c782e Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sun, 2 Dec 2012 08:41:49 +0100 Subject: [PATCH 3/7] Rename XfrToken to XfrMsg --- xfr.go | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/xfr.go b/xfr.go index 5b8a5135..84b47be3 100644 --- a/xfr.go +++ b/xfr.go @@ -1,13 +1,13 @@ package dns -// XfrToken is used when doing [IA]xfr with a remote server. -type XfrToken struct { - RR []RR // the set of RRs in the answer section of the AXFR reply message - Error error // if something went wrong, this contains the error +// XfrMsg is used when doing [IA]xfr with a remote server. +type XfrMsg struct { + RR []RR // The set of RRs in the answer section of the AXFR reply message. + Error error // If something went wrong, this contains the error. } // XfrReceive performs a [AI]xfr request (depends on the message's Qtype). It returns -// a channel of XfrToken on which the replies from the server are sent. At the end of +// a channel of *XfrMsg on which the replies from the server are sent. At the end of // the transfer the channel is closed. // It panics if the Qtype does not equal TypeAXFR or TypeIXFR. The messages are TSIG checked if // needed, no other post-processing is performed. The caller must dissect the returned @@ -20,7 +20,7 @@ type XfrToken struct { // for r := range t { // // ... deal with r.RR or r.Error // } -func (c *Client) XfrReceive(q *Msg, a string) (chan *XfrToken, error) { +func (c *Client) XfrReceive(q *Msg, a string) (chan *XfrMsg, error) { w := new(reply) w.client = c w.addr = a @@ -31,7 +31,7 @@ func (c *Client) XfrReceive(q *Msg, a string) (chan *XfrToken, error) { if err := w.send(q); err != nil { return nil, err } - e := make(chan *XfrToken) + e := make(chan *XfrMsg) switch q.Question[0].Qtype { case TypeAXFR: go w.axfrReceive(q, e) @@ -45,23 +45,23 @@ func (c *Client) XfrReceive(q *Msg, a string) (chan *XfrToken, error) { panic("dns: not reached") } -func (w *reply) axfrReceive(q *Msg, c chan *XfrToken) { +func (w *reply) axfrReceive(q *Msg, c chan *XfrMsg) { first := true defer w.conn.Close() defer close(c) for { in, err := w.receive() if err != nil { - c <- &XfrToken{nil, err} + c <- &XfrMsg{nil, err} return } if in.Id != q.Id { - c <- &XfrToken{in.Answer, ErrId} + c <- &XfrMsg{in.Answer, ErrId} return } if first { if !checkXfrSOA(in, true) { - c <- &XfrToken{in.Answer, ErrSoa} + c <- &XfrMsg{in.Answer, ErrSoa} return } first = !first @@ -70,16 +70,16 @@ func (w *reply) axfrReceive(q *Msg, c chan *XfrToken) { if !first { w.tsigTimersOnly = true // Subsequent envelopes use this. if checkXfrSOA(in, false) { - c <- &XfrToken{in.Answer, nil} + c <- &XfrMsg{in.Answer, nil} return } - c <- &XfrToken{in.Answer, nil} + c <- &XfrMsg{in.Answer, nil} } } panic("dns: not reached") } -func (w *reply) ixfrReceive(q *Msg, c chan *XfrToken) { +func (w *reply) ixfrReceive(q *Msg, c chan *XfrMsg) { var serial uint32 // The first serial seen is the current server serial first := true defer w.conn.Close() @@ -87,23 +87,23 @@ func (w *reply) ixfrReceive(q *Msg, c chan *XfrToken) { for { in, err := w.receive() if err != nil { - c <- &XfrToken{in.Answer, err} + c <- &XfrMsg{in.Answer, err} return } if q.Id != in.Id { - c <- &XfrToken{in.Answer, ErrId} + c <- &XfrMsg{in.Answer, ErrId} return } if first { // A single SOA RR signals "no changes" if len(in.Answer) == 1 && checkXfrSOA(in, true) { - c <- &XfrToken{in.Answer, nil} + c <- &XfrMsg{in.Answer, nil} return } // Check if the returned answer is ok if !checkXfrSOA(in, true) { - c <- &XfrToken{in.Answer, ErrSoa} + c <- &XfrMsg{in.Answer, ErrSoa} return } // This serial is important @@ -117,11 +117,11 @@ func (w *reply) ixfrReceive(q *Msg, c chan *XfrToken) { // If the last record in the IXFR contains the servers' SOA, we should quit if v, ok := in.Answer[len(in.Answer)-1].(*RR_SOA); ok { if v.Serial == serial { - c <- &XfrToken{in.Answer, nil} + c <- &XfrMsg{in.Answer, nil} return } } - c <- &XfrToken{in.Answer, nil} + c <- &XfrMsg{in.Answer, nil} } } panic("dns: not reached") @@ -143,7 +143,7 @@ func checkXfrSOA(in *Msg, first bool) bool { // XfrSend performs an outgoing [AI]xfr depending on the request message. The // caller is responsible for sending the correct sequence of RR sets through -// the channel c. For reasons of symmetry XfrToken is re-used. +// the channel c. For reasons of symmetry XfrMsg is re-used. // Errors are signaled via the error pointer, when an error occurs the function // sets the error and returns (it does not close the channel). // TSIG and enveloping is handled by XfrSend. @@ -151,19 +151,19 @@ func checkXfrSOA(in *Msg, first bool) bool { // Basic use pattern for sending an AXFR: // // // q contains the AXFR request -// c := make(chan *XfrToken) +// c := make(chan *XfrMsg) // var e *error // err := XfrSend(w, q, c, e) // w.Hijack() // hijack the connection so that the library doesn't close it // for _, rrset := range rrsets { // rrset is a []RR -// c <- &{XfrToken{RR: rrset} +// c <- &{XfrMsg{RR: rrset} // if e != nil { // close(c) // break // } // } // // w.Close() // Don't! Let the client close the connection -func XfrSend(w ResponseWriter, q *Msg, c chan *XfrToken, e *error) error { +func XfrSend(w ResponseWriter, q *Msg, c chan *XfrMsg, e *error) error { switch q.Question[0].Qtype { case TypeAXFR, TypeIXFR: go axfrSend(w, q, c, e) @@ -175,7 +175,7 @@ func XfrSend(w ResponseWriter, q *Msg, c chan *XfrToken, e *error) error { } // TODO(mg): count the RRs and the resulting size. -func axfrSend(w ResponseWriter, req *Msg, c chan *XfrToken, e *error) { +func axfrSend(w ResponseWriter, req *Msg, c chan *XfrMsg, e *error) { rep := new(Msg) rep.SetReply(req) rep.Authoritative = true From a115d2230a486af81aa6df2bde36bdfca67ced1a Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sun, 2 Dec 2012 08:45:47 +0100 Subject: [PATCH 4/7] Doc updates --- xfr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xfr.go b/xfr.go index 84b47be3..aeeff37c 100644 --- a/xfr.go +++ b/xfr.go @@ -9,7 +9,7 @@ type XfrMsg struct { // XfrReceive performs a [AI]xfr request (depends on the message's Qtype). It returns // a channel of *XfrMsg on which the replies from the server are sent. At the end of // the transfer the channel is closed. -// It panics if the Qtype does not equal TypeAXFR or TypeIXFR. The messages are TSIG checked if +// The messages are TSIG checked if // needed, no other post-processing is performed. The caller must dissect the returned // messages. // From 724a1567945ab4f7cb96e028106629f36596440d Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sun, 2 Dec 2012 08:47:32 +0100 Subject: [PATCH 5/7] Envelope is the correct term in the context of transfers --- xfr.go | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/xfr.go b/xfr.go index aeeff37c..13e76b71 100644 --- a/xfr.go +++ b/xfr.go @@ -1,13 +1,13 @@ package dns -// XfrMsg is used when doing [IA]xfr with a remote server. -type XfrMsg struct { +// Envelope is used when doing [IA]xfr with a remote server. +type Envelope struct { RR []RR // The set of RRs in the answer section of the AXFR reply message. Error error // If something went wrong, this contains the error. } // XfrReceive performs a [AI]xfr request (depends on the message's Qtype). It returns -// a channel of *XfrMsg on which the replies from the server are sent. At the end of +// a channel of *Envelope on which the replies from the server are sent. At the end of // the transfer the channel is closed. // The messages are TSIG checked if // needed, no other post-processing is performed. The caller must dissect the returned @@ -20,7 +20,7 @@ type XfrMsg struct { // for r := range t { // // ... deal with r.RR or r.Error // } -func (c *Client) XfrReceive(q *Msg, a string) (chan *XfrMsg, error) { +func (c *Client) XfrReceive(q *Msg, a string) (chan *Envelope, error) { w := new(reply) w.client = c w.addr = a @@ -31,7 +31,7 @@ func (c *Client) XfrReceive(q *Msg, a string) (chan *XfrMsg, error) { if err := w.send(q); err != nil { return nil, err } - e := make(chan *XfrMsg) + e := make(chan *Envelope) switch q.Question[0].Qtype { case TypeAXFR: go w.axfrReceive(q, e) @@ -45,23 +45,23 @@ func (c *Client) XfrReceive(q *Msg, a string) (chan *XfrMsg, error) { panic("dns: not reached") } -func (w *reply) axfrReceive(q *Msg, c chan *XfrMsg) { +func (w *reply) axfrReceive(q *Msg, c chan *Envelope) { first := true defer w.conn.Close() defer close(c) for { in, err := w.receive() if err != nil { - c <- &XfrMsg{nil, err} + c <- &Envelope{nil, err} return } if in.Id != q.Id { - c <- &XfrMsg{in.Answer, ErrId} + c <- &Envelope{in.Answer, ErrId} return } if first { if !checkXfrSOA(in, true) { - c <- &XfrMsg{in.Answer, ErrSoa} + c <- &Envelope{in.Answer, ErrSoa} return } first = !first @@ -70,16 +70,16 @@ func (w *reply) axfrReceive(q *Msg, c chan *XfrMsg) { if !first { w.tsigTimersOnly = true // Subsequent envelopes use this. if checkXfrSOA(in, false) { - c <- &XfrMsg{in.Answer, nil} + c <- &Envelope{in.Answer, nil} return } - c <- &XfrMsg{in.Answer, nil} + c <- &Envelope{in.Answer, nil} } } panic("dns: not reached") } -func (w *reply) ixfrReceive(q *Msg, c chan *XfrMsg) { +func (w *reply) ixfrReceive(q *Msg, c chan *Envelope) { var serial uint32 // The first serial seen is the current server serial first := true defer w.conn.Close() @@ -87,23 +87,23 @@ func (w *reply) ixfrReceive(q *Msg, c chan *XfrMsg) { for { in, err := w.receive() if err != nil { - c <- &XfrMsg{in.Answer, err} + c <- &Envelope{in.Answer, err} return } if q.Id != in.Id { - c <- &XfrMsg{in.Answer, ErrId} + c <- &Envelope{in.Answer, ErrId} return } if first { // A single SOA RR signals "no changes" if len(in.Answer) == 1 && checkXfrSOA(in, true) { - c <- &XfrMsg{in.Answer, nil} + c <- &Envelope{in.Answer, nil} return } // Check if the returned answer is ok if !checkXfrSOA(in, true) { - c <- &XfrMsg{in.Answer, ErrSoa} + c <- &Envelope{in.Answer, ErrSoa} return } // This serial is important @@ -117,11 +117,11 @@ func (w *reply) ixfrReceive(q *Msg, c chan *XfrMsg) { // If the last record in the IXFR contains the servers' SOA, we should quit if v, ok := in.Answer[len(in.Answer)-1].(*RR_SOA); ok { if v.Serial == serial { - c <- &XfrMsg{in.Answer, nil} + c <- &Envelope{in.Answer, nil} return } } - c <- &XfrMsg{in.Answer, nil} + c <- &Envelope{in.Answer, nil} } } panic("dns: not reached") @@ -143,7 +143,7 @@ func checkXfrSOA(in *Msg, first bool) bool { // XfrSend performs an outgoing [AI]xfr depending on the request message. The // caller is responsible for sending the correct sequence of RR sets through -// the channel c. For reasons of symmetry XfrMsg is re-used. +// the channel c. For reasons of symmetry Envelope is re-used. // Errors are signaled via the error pointer, when an error occurs the function // sets the error and returns (it does not close the channel). // TSIG and enveloping is handled by XfrSend. @@ -151,19 +151,19 @@ func checkXfrSOA(in *Msg, first bool) bool { // Basic use pattern for sending an AXFR: // // // q contains the AXFR request -// c := make(chan *XfrMsg) +// c := make(chan *Envelope) // var e *error // err := XfrSend(w, q, c, e) // w.Hijack() // hijack the connection so that the library doesn't close it // for _, rrset := range rrsets { // rrset is a []RR -// c <- &{XfrMsg{RR: rrset} +// c <- &{Envelope{RR: rrset} // if e != nil { // close(c) // break // } // } // // w.Close() // Don't! Let the client close the connection -func XfrSend(w ResponseWriter, q *Msg, c chan *XfrMsg, e *error) error { +func XfrSend(w ResponseWriter, q *Msg, c chan *Envelope, e *error) error { switch q.Question[0].Qtype { case TypeAXFR, TypeIXFR: go axfrSend(w, q, c, e) @@ -175,7 +175,7 @@ func XfrSend(w ResponseWriter, q *Msg, c chan *XfrMsg, e *error) error { } // TODO(mg): count the RRs and the resulting size. -func axfrSend(w ResponseWriter, req *Msg, c chan *XfrMsg, e *error) { +func axfrSend(w ResponseWriter, req *Msg, c chan *Envelope, e *error) { rep := new(Msg) rep.SetReply(req) rep.Authoritative = true From 7268c0f90aa0831edc3eb2421551cb367b2ff64c Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sun, 2 Dec 2012 09:01:23 +0100 Subject: [PATCH 6/7] Rename the axfr stuff Think the names are now more Go like and descriptive. --- xfr.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/xfr.go b/xfr.go index 13e76b71..9eac4a90 100644 --- a/xfr.go +++ b/xfr.go @@ -6,7 +6,7 @@ type Envelope struct { Error error // If something went wrong, this contains the error. } -// XfrReceive performs a [AI]xfr request (depends on the message's Qtype). It returns +// TransferIn performs a [AI]xfr request (depends on the message's Qtype). It returns // a channel of *Envelope on which the replies from the server are sent. At the end of // the transfer the channel is closed. // The messages are TSIG checked if @@ -16,11 +16,11 @@ type Envelope struct { // Basic use pattern for receiving an AXFR: // // // m contains the AXFR request -// t, e := client.XfrReceive(m, "127.0.0.1:53") +// t, e := c.TransferIn(m, "127.0.0.1:53") // for r := range t { // // ... deal with r.RR or r.Error // } -func (c *Client) XfrReceive(q *Msg, a string) (chan *Envelope, error) { +func (c *Client) TransferIn(q *Msg, a string) (chan *Envelope, error) { w := new(reply) w.client = c w.addr = a @@ -34,10 +34,10 @@ func (c *Client) XfrReceive(q *Msg, a string) (chan *Envelope, error) { e := make(chan *Envelope) switch q.Question[0].Qtype { case TypeAXFR: - go w.axfrReceive(q, e) + go w.axfrIn(q, e) return e, nil case TypeIXFR: - go w.ixfrReceive(q, e) + go w.ixfrIn(q, e) return e, nil default: return nil, nil @@ -45,7 +45,7 @@ func (c *Client) XfrReceive(q *Msg, a string) (chan *Envelope, error) { panic("dns: not reached") } -func (w *reply) axfrReceive(q *Msg, c chan *Envelope) { +func (w *reply) axfrIn(q *Msg, c chan *Envelope) { first := true defer w.conn.Close() defer close(c) @@ -79,7 +79,7 @@ func (w *reply) axfrReceive(q *Msg, c chan *Envelope) { panic("dns: not reached") } -func (w *reply) ixfrReceive(q *Msg, c chan *Envelope) { +func (w *reply) ixfrIn(q *Msg, c chan *Envelope) { var serial uint32 // The first serial seen is the current server serial first := true defer w.conn.Close() @@ -141,21 +141,21 @@ func checkXfrSOA(in *Msg, first bool) bool { return false } -// XfrSend performs an outgoing [AI]xfr depending on the request message. The +// TransferOut performs an outgoing [AI]xfr depending on the request message. The // caller is responsible for sending the correct sequence of RR sets through // the channel c. For reasons of symmetry Envelope is re-used. // Errors are signaled via the error pointer, when an error occurs the function // sets the error and returns (it does not close the channel). -// TSIG and enveloping is handled by XfrSend. +// TSIG and enveloping is handled by TransferOut. // // Basic use pattern for sending an AXFR: // // // q contains the AXFR request // c := make(chan *Envelope) // var e *error -// err := XfrSend(w, q, c, e) -// w.Hijack() // hijack the connection so that the library doesn't close it -// for _, rrset := range rrsets { // rrset is a []RR +// err := TransferOut(w, q, c, e) +// w.Hijack() // hijack the connection so that the package doesn't close it +// for _, rrset := range rrsets { // rrsets is a []RR // c <- &{Envelope{RR: rrset} // if e != nil { // close(c) @@ -163,10 +163,10 @@ func checkXfrSOA(in *Msg, first bool) bool { // } // } // // w.Close() // Don't! Let the client close the connection -func XfrSend(w ResponseWriter, q *Msg, c chan *Envelope, e *error) error { +func TransferOut(w ResponseWriter, q *Msg, c chan *Envelope, e *error) error { switch q.Question[0].Qtype { case TypeAXFR, TypeIXFR: - go axfrSend(w, q, c, e) + go xfrOut(w, q, c, e) return nil default: return nil @@ -175,7 +175,7 @@ func XfrSend(w ResponseWriter, q *Msg, c chan *Envelope, e *error) error { } // TODO(mg): count the RRs and the resulting size. -func axfrSend(w ResponseWriter, req *Msg, c chan *Envelope, e *error) { +func xfrOut(w ResponseWriter, req *Msg, c chan *Envelope, e *error) { rep := new(Msg) rep.SetReply(req) rep.Authoritative = true From d0db571db1329b1c4e7d63dd9a067575216f43cf Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sun, 2 Dec 2012 09:05:48 +0100 Subject: [PATCH 7/7] update todo --- TODO.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO.markdown b/TODO.markdown index 46d679ab..6198381a 100644 --- a/TODO.markdown +++ b/TODO.markdown @@ -7,7 +7,7 @@ * sign * verify * Use BIND10 memory efficient zone structure? -* make more use of io.Reader/io.Writer +* copy srv/mx sorting from base library ## Nice to have