Commit Graph

301 Commits

Author SHA1 Message Date
Tom Thorogood 17c1bc6792
Eliminate lexer goroutines (#792)
* Eliminate zlexer goroutine

This replaces the zlexer goroutine and channels with a zlexer struct
that maintains state and provides a channel-like API.

* Eliminate klexer goroutine

This replaces the klexer goroutine and channels with a klexer struct
that maintains state and provides a channel-like API.

* Merge scan into zlexer and klexer

This does result in tokenText existing twice, but it's pretty simple
and small so it's not that bad.

* Avoid using text/scanner.Position to track position

* Track escape within zlexer.Next

* Avoid zl.commt check on space and tab in zlexer

* Track stri within zlexer.Next

* Track comi within zlexer.Next

There is one special case at the start of a comment that needs to be
handled, otherwise this is as simple as stri was.

* Use a single token buffer in zlexer

This is safe as there is never both a non-empty string buffer and a
non-empty comment buffer.

* Don't hardcode length of zl.tok in zlexer

* Eliminate lex.length field

This is always set to len(l.token) and is only queried in a few places.

It was added in 47cc5b052d without any
obvious need.

* Add whitespace to klexer.Next

* Track lex within klexer.Next

* Use a strings.Builder in klexer.Next

* Simplify : case in klexer.Next

* Add whitespace to zlexer.Next

* Change for loop style in zlexer.Next and klexer.Next

* Surface read errors in zlexer

* Surface read errors from klexer

* Remove debug line from parseKey

* Rename tokenText to readByte

* Make readByte return ok bool

Also change the for loop style to match the Next for loops.

* Make readByte errors sticky

klexer.Next calls readByte separately from within the loop. Without
readByte being sticky, an error that occurs during that readByte call
may be lost.

* Panic in testRR if the error is non-nil

* Add whitespace and unify field setting in zlexer.Next

* Remove eof fields from zlexer and klexer

With readByte having sticky errors, this no longer needed. zl.eof = true
was also in the wrong place and could mask an unbalanced brace error.

* Merge zl.tok blocks in zlexer.Next

* Split the tok buffer into separate string and comment buffers

The invariant of stri > 0 && comi > 0 never being true was broken when
x == '\n' && !zl.quote && zl.commt && zl.brace != 0 (the
"If not in a brace this ends the comment AND the RR" block).

Split the buffer back out into two separate buffers to avoid clobbering.

* Replace token slices with arrays in zlexer

* Add a NewRR benchmark

* Move token buffers into zlexer.Next

These don't need to be retained across Next calls and can be stack
allocated inside Next. This drastically reduces memory consumption as
they accounted for nearly half of all the memory used.

name      old alloc/op   new alloc/op   delta
NewRR-12    9.72kB ± 0%    4.98kB ± 0%  -48.72%  (p=0.000 n=10+10)

* Add a ReadRR benchmark

Unlike NewRR, this will use an io.Reader that does not implement any
methods aside from Read. In particular it does not implement
io.ByteReader.

* Avoid using a bufio.Reader for io.ByteReader readers

At the same time use a smaller buffer size of 1KiB rather than the
bufio.NewReader default of 4KiB.

name       old time/op    new time/op    delta
NewRR-12     11.0µs ± 3%     9.5µs ± 2%  -13.77%  (p=0.000 n=9+10)
ReadRR-12    11.2µs ±16%     9.8µs ± 1%  -13.03%  (p=0.000 n=10+10)

name       old alloc/op   new alloc/op   delta
NewRR-12     4.98kB ± 0%    0.81kB ± 0%  -83.79%  (p=0.000 n=10+10)
ReadRR-12    4.87kB ± 0%    1.82kB ± 0%  -62.73%  (p=0.000 n=10+10)

name       old allocs/op  new allocs/op  delta
NewRR-12       19.0 ± 0%      17.0 ± 0%  -10.53%  (p=0.000 n=10+10)
ReadRR-12      19.0 ± 0%      19.0 ± 0%     ~     (all equal)

ReadRR-12    11.2µs ±16%     9.8µs ± 1%  -13.03%  (p=0.000 n=10+10)

* Surface any remaining comment from zlexer.Next

* Improve comment handling in zlexer.Next

This both fixes a regression where comments could be lost under certain
circumstances and now emits comments that occur within braces.

* Remove outdated comment from zlexer.Next and klexer.Next

* Delay converting LF to space in braced comment

* Fixup TestParseZoneComments

* Remove tokenUpper field from lex

Not computing this for every token, and instead only
when needed is a substantial performance improvement.

name       old time/op    new time/op    delta
NewRR-12     9.56µs ± 0%    6.30µs ± 1%  -34.08%  (p=0.000 n=9+10)
ReadRR-12    9.93µs ± 1%    6.67µs ± 1%  -32.77%  (p=0.000 n=10+10)

name       old alloc/op   new alloc/op   delta
NewRR-12       824B ± 0%      808B ± 0%   -1.94%  (p=0.000 n=10+10)
ReadRR-12    1.83kB ± 0%    1.82kB ± 0%   -0.87%  (p=0.000 n=10+10)

name       old allocs/op  new allocs/op  delta
NewRR-12       17.0 ± 0%      17.0 ± 0%     ~     (all equal)
ReadRR-12      19.0 ± 0%      19.0 ± 0%     ~     (all equal)

* Update ParseZone documentation to match comment changes

The zlexer code was changed to return comments more often, so update the
ParseZone documentation to match.
2018-10-15 17:42:31 +10:30
Tom Thorogood ead9678cbc
Run go fmt on package (#759)
This is go fmt from go1.11 and so it picks up the new map formatting
heuristic.

See golang/go@542ea5ad91.
2018-09-27 03:06:02 +09:30
Miek Gieben dcdbddd810
ClassANY: don't convert CLASS255 to ANY (#618)
* ClassANY: don't convert CLASS255 to ANY

Class "ANY" is wireformat only. In zonefile you can use CLASS255, but
when String-ing we convert this into "ANY" which is wrong. I.e. this
means we can't read back our own update.

Bit of a kludge to work around this, as I'm not sure we can just remove
ANY from the ClassToString map.
2018-01-07 17:57:04 +00:00
Miek Gieben 57a0d1a2cf
458+dep (#591)
* Add support for Ed25519 DNSSEC signing from RFC 8080

Note: The test case from RFC 8080 has been modified
to correct the missing final brace, but is otherwise
present as-is.

* Explain why ed25519 is special cased in (*RRSIG).Sign

* Explain use of ed25519.GenerateKey in readPrivateKeyED25519

* Add dep

This is PR #458 with the dependency added into it.
2017-11-27 10:49:53 +00:00
Miek Gieben 2ae4695cc7
Implement CSYNC (#585)
Implement the CSYNC record.

Fixes #290

Long overdue, lets add this record. Similar in vain as NSEC/NSEC3, we
need to implement len() our selves. Presentation format parsing and
tests are done as well.

This is CoreDNS running with CSYNC support, `dig` doesn't support this
at the moment, so:

~~~
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40323
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;csync.example.org.		IN	TYPE62

;; ANSWER SECTION:
csync.example.org.	10	IN	TYPE62	\# 12 000335240042000460000008

;; AUTHORITY SECTION:
example.org.		10	IN	NS	a.iana-servers.net.
example.org.		10	IN	NS	b.iana-servers.net.
~~~
2017-11-25 08:19:06 +00:00
JeremyRand cdb76b64a3 Spelling fixes (#583)
* Doc: fix misspelling.

Found via "misspell" static analyzer.

* Parse test: fix misspellings.

Found via "misspell" static analyzer.
2017-11-24 08:14:48 +00:00
Miek Gieben acff9ce3fa
Fuzzing the text parser: a few fixes (#579)
I'm fuzzing the text parser and that turned up these two. Will do
further fuzzing with these fixes in.
2017-11-20 18:07:37 +00:00
Miek Gieben 2a67631d76
cleanup: remove debug.Printf from scanner (#573)
Remove the debug.Printf stuff from scanner and some other style nits.
2017-11-17 10:48:42 +00:00
Miek Gieben cfe41281c2
txt parser: fix goroutine leak (#570)
* txt parser: fix goroutine leak

When a higher level (grammar or syntax) error was encountered the lower
level zlexer routine would be left open and trying to send more tokens
on the channel c. This leaks a goroutine, per failed parse...

This PR fixes this by signalling this error - by canceling a context -
retrieving any remaining items from the channel, so zlexer can return.

It also adds a goroutine leak test that can be re-used in other tests,
the TestParseBadNAPTR test uses this leak detector.

The private key parsing code had the same bug and is also fixed in this
PR.

Fixes #586
Fixes https://github.com/coredns/coredns/issues/1233

* sem not needed anymore
2017-11-17 10:47:28 +00:00
Miek Gieben 9cfd42f1df
Tests: add ListenAndServe tests (#562)
This increases the test coverage as these methods where not tested.
Add some cosmetic changes to the mix.
2017-11-10 10:11:23 +00:00
Miek Gieben 348c84f37e
Test: remove all Logf/Log (#547)
Move some of them to Errorf and friends, but most of them are just
gone: This make go test -v actually readable.

Remove a bunch of test that used ipv6 on localhost as this does not work
on Travis.
2017-11-03 15:50:01 +00:00
Richard Gibson eccf8bbe83 Correctly parse omitted TTLs and relative domains (#513)
* Fix $TTL handling
* Error when there is no TTL for an RR
* Fix relative name handling
* Error when a relative name is used without an origin (cf. https://tools.ietf.org/html/rfc1035#section-5.1 )

Fixes #484
2017-09-26 11:15:37 -04:00
Miek Gieben babbdab23a parsing: error on unbalanced braces (#489)
When done parsing, check if we have balanced braces, if not error out.

Fixes #488
2017-05-23 11:21:56 +01:00
Miek Gieben 767422ac12 Add AVC record (#480)
See
https://www.iana.org/assignments/dns-parameters/AVC/avc-completed-template
for the template, a new record that is (again) a mirror of the TXT
record. For lack of a better name, name the rdata Txt - as we do in SPF
and TXT.
2017-03-29 22:17:13 +02:00
Jon Nappi c862b7e359 Replace Atoi with ParseUint where appropriate (#470)
* replace Atoi with ParseUint where appropriate

* more Atoi replacements
2017-03-10 21:57:03 +00:00
Richard Gibson 21314e1838 Fix TXT RDATA parsing (#421)
* Test for proper parsing of whitespace-separated (TXT) character-strings

* Properly parse whitespace-separated (TXT) character-strings

* Remove non-RFC treatment of backslash sequences in character-strings

Fixes gh-420

* For tests, remove non-RFC treatment of backslashes in domain names
2016-12-02 09:34:49 +00:00
Miek Gieben 46df8c9462 Fix for miekg/dns issue #289: support the SMIMEA record (#410)
1) Refactoring of tlsa.go
   - moved routine to create the certificate rdata to its own go module
     as this is shared between TLSA and SMIMEA records
2) Added support for creating an SMIMEA domain name
3) Developed in accordance with draft-ietf-dane-smime-12 RFC

Miek,

Submitting for your review. Happy to make any recommended changes or
address omissions.

Lightly tested against our internal DNS service which hosts DANE
SMIMEA records for our email certificates.

Parse tests are added.
2016-10-17 18:09:52 +01:00
Miek Gieben db96a2b759 Handle empty salt value (#392)
When removing the reflection we inadvertely also removed the code for
handling empty salt values in NSEC3 and NSEC3PARAM. These are somewhat
annoying because the text representation is '-', which is not valid hex.
2016-07-25 20:20:27 -07:00
Miek Gieben dbffa4b057 Kill all reflection when packing/unpacking RR (#372)
Update the size-xxx-member tags to point to another field in the struct
that should be used for the length in that field. Fix NSEC3/HIP and TSIG
to use to this and generate the correct pack/unpack functions for them.

Remove IPSECKEY from the lib and handle it as an unknown record - it is
such a horrible RR, needed kludges before - now just handle it as an
unknown RR.

All types now use generated pack and unpack functions. The blacklist is
removed.
2016-06-12 18:31:50 +01:00
shawnps 0cea3842b9 gofmt -s 2016-01-22 08:44:49 -08:00
Miek Gieben f520760857 Lowercase all error msg from the tests 2015-11-26 14:12:38 +00:00
Masa Sekimura a9a71b9628 gofmt and revert unnecessary changes 2015-09-30 09:08:17 -07:00
Masayoshi Sekimura a14e77725f tidyup a little with the latest golang.org/x/tools/cmd/vet 2015-09-29 23:04:25 -07:00
Miek Gieben 79547a0341 Add Dedup function
Add function that dedups a list of RRs. Work on strings, which
adds garbage, but seems to be the least intrusive and takes the
last amount of memory.

Some fmt changes snook in as well.
2015-08-24 22:02:57 +01:00
Filippo Valsorda 034c247229 Refactor DNSSEC to use crypto.{PrivateKey,Signer}
This will allow RRSIG.Sign to use generic crypto.Signer implementations.

This is a interface breaking change, even if the required changes are most
likely just type asserions from crypto.PrivateKey to the underlying type or
crypto.Signer.
2015-08-19 17:51:02 +01:00
Miek Gieben 21b35db538 Remove the NSAP record
The NSAP was not implemented correctly, see #239. Just remove it. It will still work as unknown RR.
2015-08-10 07:26:35 +01:00
Miek Gieben 2839b93f6b merge conflict 2015-07-28 21:45:20 +01:00
Miek Gieben 9d8cd1bfd9 Test parsing empty target 2015-07-28 07:20:54 +01:00
Miek Gieben 179a68fbec Some small fixes 2015-07-27 22:12:46 +01:00
Miek Gieben a34cf6798a Fix URI record
When the URI record became an RFC they slightly changed the format.
Make the needed changes.
2015-07-21 07:47:38 +01:00
Roland Shoemaker ce1812cfaf Add byte packing/unpacking test 2015-07-20 13:21:13 -07:00
Roland Shoemaker 020002b9e0 Switch setCAA, CAA.String to presentation format, add various encoding helpers 2015-06-17 16:06:31 -07:00
Alex Sergeyev 0bc16d74c9 Added comment to commented-out testcase 2015-05-07 12:12:39 -04:00
Alex Sergeyev 32bf0823e2 Support for almost all possible ways to format HINFO record 2015-05-07 12:09:05 -04:00
Alex Sergeyev 2e9176243e Updated NSAP support according to RFC1706
New text format 0x and no more length in the object itself.
2015-05-07 10:18:47 -04:00
Alex Sergeyev d2bed60478 Fixed SSHFP parsing when multiple lines used for text representation. 2015-05-07 09:50:44 -04:00
Miek Gieben 03d7235729 Add TLSA parsing tests 2015-05-07 12:47:42 +01:00
Miek Gieben 8bcf792243 Playing with TLSA records 2015-05-07 07:42:55 +01:00
Alex Sergeyev 627287e675 Issue with TLSA parsing identified 2015-05-06 23:25:33 -04:00
Miek Gieben 12197b977e In TXT records break up large chunks in 255 bytes
TXT records consist out of multiple 255 byte chunk. When parsing
a chunk that is too large, Go DNS would happily add it. This would
only fail when packing the message.

Change this to auto-chunking when reading the TXT records from file
into 255 byte sized chunks.
2015-03-04 09:33:37 +00:00
Michael Haro 6b54d9f863 Revert "Use gofmt to simplify code"
This reverts commit 48dce403d5.
2015-02-26 01:48:30 -08:00
Michael Haro 7f051930ff Use %v as the format arg for errors 2015-02-26 00:49:59 -08:00
Michael Haro 48dce403d5 Use gofmt to simplify code 2015-02-26 00:38:33 -08:00
Michael Haro 4437868b75 Replace t.Logf("%s", var) with t.Log(var) 2015-02-26 00:30:40 -08:00
Michael Haro 2fb2a25e84 More test clean up
Remove trailing \n from t.Log and t.Error messages as it's unnecessary.

In some instances, combine multiple t.Error()s into one

To provide more consistency across the tests, rename e to err and use %v
as the format arg for errors.

Replace Logf and Errorf with Log and Error when it made sense.  For
example t.Errorf("%v", err) to t.Error(err)
2015-02-25 22:14:21 -08:00
Michael Haro f995f1aff3 Convert tests from being t.Log(..) then t.Fail() to just t.Error(...) as
t.Error(...) does both and makes it more clear which messages are errors
vs information log messages.
2015-02-23 17:43:07 -08:00
Miek Gieben 67945c119e A bunch of golint fixes
The proposed vars names are a nono, because they break the API.
Things left: document each RR and zscan_rr.go has some funcky if-then-elses.
2015-02-19 09:58:33 +00:00
Miek Gieben 50890090cb Merge branch 'ipseckey'
Tentatively merging.
2015-01-27 08:17:50 +00:00
Miek Gieben 477cb4d3fa Implement IPSECKEY
IPSECKEY is kinda strange because it has a type selector which tells
what type a later rdata field has. The type can be a domainname, address
or v6 address. You sort of wish Go would have a union type for this, but
alas.
Currently this is implemented as:

	GatewayA    net.IP `dns:"a"`
	GatewayAAAA net.IP `dns:"aaaa"`
	GatewayName string `dns:"domain-name"`

In the IPSECKEY. Only one of these is active at any one time. When
parsing/packing and unpacking the value of GatewayType is checked
to see what to do.

Parsing from strings is also implemented properly and tested. The Unpack
function still needs work.
2015-01-25 10:58:30 +00:00
Filippo Valsorda e9faa971b3 Refactor the DNSSEC private key code
Now PrivateKey is an interface exposing Sign() and String(). Common
implementations are wrappers for {rsa|dsa|ecdsa}.PrivateKey but
this allows for custom signers, and abstracts away the private-ops
code to a single place.
2015-01-23 13:04:29 -08:00