From 6ddb9ab88bb4d6adb7dee07634137ec7c99dffab Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Sun, 12 Feb 2012 21:50:02 +0100 Subject: [PATCH] Txt record parsing works -- need to look at the on-the-wire stuff --- TODO.markdown | 7 ++----- dns_test.go | 2 +- parse_test.go | 17 ++++++++--------- server_test.go | 2 +- types.go | 14 +++++++++++--- zscan_rr.go | 22 ++++++++++++++++------ 6 files changed, 39 insertions(+), 25 deletions(-) diff --git a/TODO.markdown b/TODO.markdown index 8220d111..96162d67 100644 --- a/TODO.markdown +++ b/TODO.markdown @@ -4,15 +4,13 @@ Must of the stuff is working, but there is a list of smaller things that need to be fixed. * Parsing - * TXT record isn't parsed correctly, if followed by a comment - - Need to make " important in the parsing * Speed, we can always go faster. A simple reflect server now hits 30/40K qps * Add handy zone data structure (r/b tree)? Or not... * Use the Exchange structure to deal with errors when resolving, esp. Timeout * IsSubdomain, IsGlue helper functions; * SaltLength in NSEC3 is ugly to set, should be automatically done. There are prolly a few more - settings just like that -- need to look at them. - -edns NSID is another + settings just like that -- need to look at them. + -edns NSID is another * Add tsig check in 'q'? * More RRs to add. Parsing of strings within the rdata * Unknown RR parsing @@ -23,7 +21,6 @@ things that need to be fixed. * ListenAndServe has trouble with v6: Failed to setup the udp6 server: listen udp6 :8053: address already in use Failed to setup the tcp6 server: listen tcp6 :8053: address already in use -* Latest weekly breaks reflect, expected to be fixed in the next weekly. ## Examples to add diff --git a/dns_test.go b/dns_test.go index 9eb44143..9fb39188 100644 --- a/dns_test.go +++ b/dns_test.go @@ -55,7 +55,7 @@ func TestPackUnpack2(t *testing.T) { x := new(RR_TXT) x.Hdr = RR_Header{Name: dom, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0} - x.Txt = "heelalaollo" + x.Txt = []string{"heelalaollo"} m.Extra[0] = x m.Answer[0] = rr diff --git a/parse_test.go b/parse_test.go index ce22ddf7..795356ae 100644 --- a/parse_test.go +++ b/parse_test.go @@ -199,15 +199,14 @@ func TestParseNSEC(t *testing.T) { func TestQuotes(t *testing.T) { tests := map[string]string{ - `t.example.com. IN TXT "a bc"`: "t.example.com.\t3600\tIN\tTXT\t\"a bc\"", + `t.example.com. IN TXT "a bc"`: "t.example.com.\t3600\tIN\tTXT\t\"a bc\"", `t.example.com. IN TXT "a - bc"`: "t.example.com.\t3600\tIN\tTXT\t\"a\n bc\"", - `t.example.com. IN TXT "aaa" ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"", - `t.example.com. IN TXT "abc" "DEF"`: "t.example.com.\t3600\tIN\tTXT\t\"abcDEF\"", -// `t.example.com. IN TXT "abc" ( "DEF" )`: "t.example.com.\t3600\tIN\tTXT\t", -// `t.example.com. IN TXT;`: "t.example.com.\t3600\tIN\tTXT\t", -// `t.example.com. IN TXT ;`: "t.example.com.\t3600\tIN\tTXT\t", -// `t.example.com. IN TXT aaa ;`: "t.example.com.\t3600\tIN\tTXT\t \"aaaa\"", + bc"`: "t.example.com.\t3600\tIN\tTXT\t\"a\n bc\"", + `t.example.com. IN TXT "aaa" ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"", + `t.example.com. IN TXT "abc" "DEF"`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"", + `t.example.com. IN TXT "abc" ( "DEF" )`: "t.example.com.\t3600\tIN\tTXT\t\"abc\" \"DEF\"", + `t.example.com. IN TXT aaa ;`: "t.example.com.\t3600\tIN\tTXT\t\"aaa \"", + `t.example.com. IN TXT aaa aaa;`: "t.example.com.\t3600\tIN\tTXT\t\"aaaaaa\"", // `t.example.com. IN TXT aaa`: "t.example.com.\t3600\tIN\tTXT\t\"aaa\"", // "cid.urn.arpa. NAPTR 100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.": // "cid.urn.arpa.\t3600\tIN\tNAPTR\t100 50 \"s\" \"z3950+I2L+I2C\" \"\" _z3950._tcp.gatech.edu.", @@ -226,7 +225,7 @@ func TestQuotes(t *testing.T) { continue } if rr.String() != o { - t.Logf("`%s' should be equal to\n`%s', but is `%s'\n", i, o, rr.String()) + t.Logf("`%s' should be equal to\n`%s', but is\n`%s'\n", i, o, rr.String()) t.Fail() } else { t.Logf("RR is OK: `%s'", rr.String()) diff --git a/server_test.go b/server_test.go index d98180b5..6ca9be03 100644 --- a/server_test.go +++ b/server_test.go @@ -10,7 +10,7 @@ func HelloServer(w ResponseWriter, req *Msg) { m.SetReply(req) m.Extra = make([]RR, 1) - m.Extra[0] = &RR_TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: "Hello world"} + m.Extra[0] = &RR_TXT{Hdr: RR_Header{Name: m.Question[0].Name, Rrtype: TypeTXT, Class: ClassINET, Ttl: 0}, Txt: []string{"Hello world"}} buf, _ := m.Pack() w.Write(buf) } diff --git a/types.go b/types.go index 98e5c8e0..ed257ebe 100644 --- a/types.go +++ b/types.go @@ -370,7 +370,7 @@ func (rr *RR_SOA) Len() int { type RR_TXT struct { Hdr RR_Header - Txt string "txt" + Txt []string "txt" } func (rr *RR_TXT) Header() *RR_Header { @@ -378,11 +378,19 @@ func (rr *RR_TXT) Header() *RR_Header { } func (rr *RR_TXT) String() string { - return rr.Hdr.String() + "\"" + rr.Txt + "\"" + s := rr.Hdr.String() + for i, s1 := range rr.Txt { + if i > 0 { + s += " " + "\"" + s1 + "\"" + } else { + s += "\"" + s1 + "\"" + } + } + return s } func (rr *RR_TXT) Len() int { - return rr.Hdr.Len() + len(rr.Txt) // TODO: always works? + return rr.Hdr.Len() + len(rr.Txt) } type RR_SRV struct { diff --git a/zscan_rr.go b/zscan_rr.go index 829d6fc9..12e8df6e 100644 --- a/zscan_rr.go +++ b/zscan_rr.go @@ -709,24 +709,34 @@ func setTXT(h RR_Header, c chan lex, f string) (RR, *ParseError) { // Get the remaining data until we see a NEWLINE quote := false + quoted := false // unquoted strings are also allowed l := <-c - var s string + i := 0 + s := make([]string, i) + if l.value == _QUOTE { + quoted = true + } for l.value != _NEWLINE && l.value != _EOF { println("SEEN", l.value, l.token) switch l.value { case _STRING: - if quote { - s += l.token - } + s = append(s, l.token) + i++ case _BLANK: - if quote { + if !quoted { + // i = 0, shouldn't happen here + s[i-1] += l.token + l = <-c + continue + } + if quoted && quote { // _BLANK can only be seen in between txt parts. return nil, &ParseError{f, "bad TXT Txt", l} } case _QUOTE: quote = !quote default: - return nil, &ParseError{f, "bad TXT", l} + return nil, &ParseError{f, "bad TXT Txt", l} } l = <-c }