Commit Graph

3730 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
Yasar Alev 4a9ca7e98d add user link (#790) 2018-10-12 22:15:26 +01:00
Miek Gieben d74956db7b Release 1.0.13 2018-10-10 07:39:49 +01:00
Tom Thorogood dad917d8de Test coverage for all packages and merge Travis builds (#781)
This halves the number of Travis builds that will run, while adding
coverage testing to the dnsutil package.
2018-10-09 18:46:58 +01:00
Tom Thorogood a3f088363b Hold srv.lock while calling SetReadDeadline (#780)
* Hold srv.lock while calling SetReadDeadline

* Only hold the read lock in readTCP and readUDP
2018-10-09 18:46:15 +01:00
Tom Thorogood e6cede5dc8 Use an atomic int32 in checkInProgressQueriesAtShutdownServer (#779) 2018-10-09 18:43:08 +01:00
Tom Thorogood 39265ac07f Prevent a checkInProgressQueriesAtShutdownServer panic (#778)
* Prevent a checkInProgressQueriesAtShutdownServer panic

* Fix typo in comment
2018-10-09 18:41:42 +01:00
Tom Thorogood ac339476d7 Remove RunLocalUDPServerUnsafe test method (#777)
Instead of having a separate RunLocalUDPServerUnsafe, we can use the
functional options added to RunLocalUDPServerWithFinChan in ab16005053.
2018-10-09 18:41:23 +01:00
Alexey Naidyonov c0283a2028 Allows larger offset in $GENERATE (#776)
Although BIND9 documentations does not specify the possible size of offset
in $GENERATE clause, it clearly says that range must be a positive integer
between 0 and (2^31)-1. Moreover, BIND perfectly supports large offsets
which might be really handy when you're dealing with large intranets. I.e.
consider following case

```
$GENERATE 0-255 dhcp-${0,4,d}   A 10.0.0.$
$GENERATE 0-255 dhcp-${256,4,d} A 10.0.1.$
$GENERATE 0-255 dhcp-${512,4,d} A 10.0.2.$
...
```

This change removes offset size check and introduces check that
0 >= (start + offset) and (end + offset) < (2^31)-1.
2018-10-05 18:30:27 +01:00
Tom Thorogood 7eca355503 Run dep ensure -update (#770)
This uses the latest dep as of golang/dep@3c04147.

While we're here, add the missing constraints to Gopkg.toml.
2018-10-05 18:29:45 +01:00
Tom Thorogood 0d29b283ac
Optimise sprintX functions in types.go (#757)
* Simplify appendByte

* Add test case and benchmark for sprintName

* Add test case and benchmark for sprintTxtOctet

* Add test case and benchmark for sprintTxt

* Use strings.Builder for sprint* functions in types.go

* Use writeByte helper in unpackString

* Rename writeByte to writeEscapedByte

This better captures the purpose of this function.
2018-10-06 02:06:59 +09:30
Tom Thorogood 36ffedf7d0
Avoid overriding aLongTimeAgo read deadline (#774)
* Avoid overriding aLongTimeAgo read deadline

The (*Server).readTCP and (*Server).readUDP methods both call
SetReadDeadline. If they race with ShutdownContext, they can override
the aLongTimeAgo read deadline that is set in ShutdownContext. That
will cause ShutdownContext to hang or timeout.

* Reword readTCP comment
2018-10-06 01:46:28 +09:30
Tom Thorogood 7ca2be95a9 NSEC type bitmap packing bug (#768)
* Add test case for NSEC after packing and unpacking

This is ported from:
https://gist.github.com/cesarkuroiwa/ebc2b4fb1103a7e88824865184f0c73c

* Clear msg data after pointer in packDomainName
2018-10-04 07:39:45 +01:00
Tom Thorogood 008c8ca764 Explicitly panic after (*response).Close (#769)
* Explicitly panic after (*response).Close

* Prefix panics with package name

* Harden TestResponseAfterClose by comparing panic message
2018-10-04 07:39:21 +01:00
Tom Thorogood c10ce5142a Fix race on loop variable in TestConcurrentExchanges (#773) 2018-10-04 07:24:09 +01:00
Miek Gieben ba6747e8a9 Release 1.0.12 2018-09-29 17:16:31 +01:00
Miek Gieben cef340ab2c Fix vendoring
Signed-off-by: Miek Gieben <miek@miek.nl>
2018-09-29 17:15:41 +01:00
Miek Gieben 26223ef466 Release 1.0.11 2018-09-29 16:53:57 +01:00
Evgenij Vrublevskij edac0c6ab3 Rollback PR #738 because it breaks compatibility with Windows (#765) 2018-09-29 10:25:59 +01:00
Tom Thorogood 068c7e7c81 Rework and optimise ServeMux (#754)
* Avoid using pointer to sync.RWMutex in ServeMux

* Initialize ServeMux.z only when needed.

This means the zero ServeMux is now valid and empty.

* Add benchmark for ServeMux.match

* Use strings.ToLower once in ServeMux.match

strings.ToLower has a special path for ASCII-only (which q always should
be), and avoids all allocations if the string is already lowercase
(which most DNS labels should be).

* Move NextLabel into for clause in ServeMux.match

* Make ServeMux.ServeDNS easier to read

* Fix the documentation of ServeMux.ServeDNS

* Invoke HandleFailed directly in ServeMux.ServeDNS

* Bail early in ServeMux.match if Handle never called

* Fix typo in ServeMux.match

* Improve documentation of ServeMux

This just splits the massive wall of text up so it's easier to follow.

* Fix typo in ServeMux.HandleRemove documentation

* Replace strings.ToLower with once-allocating version

strings.ToLower allocates twice for uppercase ASCII which causes an
overall regression for this changeset. By writing our own custom version
here we can avoid that allocation.

When https://go-review.googlesource.com/c/go/+/137575 lands in a go
release this can be removed.
2018-09-27 07:48:02 +01:00
Tom Thorogood 45e481ce44 Fix unpackString bug: 127 DEL is unprintable (#755)
This case previously differed from UnpackDomainName in
msg.go and both sprintTxtOctet and appendTXTStringByte in
types.go and was incorrect.
2018-09-27 07:47:48 +01:00
Tom Thorogood 7482521355 Replace the trigger type with chan in server_test.go (#760)
* Replace the trigger type with chan in server_test.go

This was a lot of code to do very little.

* Check the error from ActivateAndServe in TestHandlerCloseTCP

May as well add this missing error check in while we're here.
2018-09-26 21:04:11 +01:00
Tom Thorogood 7f61c6631b
Fix dominikh/go-tools nits (#758)
* Remove unused functions and consts

* Address gosimple nits

* Address staticcheck nits

This excludes several that were intentional or weren't actual errors.

* Reduce size of lex struct

This reduces the size of the lex struct by 8 bytes from:
  lex.token string: 0-16 (size 16, align 8)
  lex.tokenUpper string: 16-32 (size 16, align 8)
  lex.length int: 32-40 (size 8, align 8)
  lex.err bool: 40-41 (size 1, align 1)
  lex.value uint8: 41-42 (size 1, align 1)
  padding: 42-48 (size 6, align 0)
  lex.line int: 48-56 (size 8, align 8)
  lex.column int: 56-64 (size 8, align 8)
  lex.torc uint16: 64-66 (size 2, align 2)
  padding: 66-72 (size 6, align 0)
  lex.comment string: 72-88 (size 16, align 8)
to:
  lex.token string: 0-16 (size 16, align 8)
  lex.tokenUpper string: 16-32 (size 16, align 8)
  lex.length int: 32-40 (size 8, align 8)
  lex.err bool: 40-41 (size 1, align 1)
  lex.value uint8: 41-42 (size 1, align 1)
  lex.torc uint16: 42-44 (size 2, align 2)
  padding: 44-48 (size 4, align 0)
  lex.line int: 48-56 (size 8, align 8)
  lex.column int: 56-64 (size 8, align 8)
  lex.comment string: 64-80 (size 16, align 8)

* Reduce size of response struct

This reduces the size of the response struct by 8 bytes from:
  response.msg []byte: 0-24 (size 24, align 8)
  response.hijacked bool: 24-25 (size 1, align 1)
  padding: 25-32 (size 7, align 0)
  response.tsigStatus error: 32-48 (size 16, align 8)
  response.tsigTimersOnly bool: 48-49 (size 1, align 1)
  padding: 49-56 (size 7, align 0)
  response.tsigRequestMAC string: 56-72 (size 16, align 8)
  response.tsigSecret map[string]string: 72-80 (size 8, align 8)
  response.udp *net.UDPConn: 80-88 (size 8, align 8)
  response.tcp net.Conn: 88-104 (size 16, align 8)
  response.udpSession *github.com/tmthrgd/dns.SessionUDP: 104-112 (size 8, align 8)
  response.writer github.com/tmthrgd/dns.Writer: 112-128 (size 16, align 8)
  response.wg *sync.WaitGroup: 128-136 (size 8, align 8)
to:
  response.msg []byte: 0-24 (size 24, align 8)
  response.hijacked bool: 24-25 (size 1, align 1)
  response.tsigTimersOnly bool: 25-26 (size 1, align 1)
  padding: 26-32 (size 6, align 0)
  response.tsigStatus error: 32-48 (size 16, align 8)
  response.tsigRequestMAC string: 48-64 (size 16, align 8)
  response.tsigSecret map[string]string: 64-72 (size 8, align 8)
  response.udp *net.UDPConn: 72-80 (size 8, align 8)
  response.tcp net.Conn: 80-96 (size 16, align 8)
  response.udpSession *github.com/tmthrgd/dns.SessionUDP: 96-104 (size 8, align 8)
  response.writer github.com/tmthrgd/dns.Writer: 104-120 (size 16, align 8)
  response.wg *sync.WaitGroup: 120-128 (size 8, align 8)
2018-09-27 04:02:05 +09: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
Tom Thorogood 60d113313c Move ServeMux into seperate file (#753)
This reduces the clutter in server.go.
2018-09-26 10:20:48 +01:00
Daniel Selifonov ab16005053 Bugfix for miekg/dns#748 (#749)
* Bugfix for miekg/dns#748

w.msg was being prematurely cleared prior to use by TsigVerify

* Modified patch after feedback from tmthrgd

Added a disposeBuffer method to the server that's passed a response. This wipes the reference to and frees the buffer used to store the message after TSIG validation has occured, not before. Since the pool is an attribute of the server (and the logic refers to a server UDPSize attribute), it made sense to make this a function of the server rather than a function of the response.

* Added TestServerRoundtripTsig to server_test.go

This test generates a TSIG signed query, and makes sure that server TSIG validation does not produce an error.

* Fixed data races introduced by TestServerRoundtripTsig

* Simplified error signalling in TestServerRoundtripTsig

* RunLocalUDPServerWithFinChan variadic closure argument added

This (clever hack suggested by tmthrgd) allows specifying field values (like TsigSecret) on Server instances at test time without making the race detector grouchy, but is backwards compatible with existing invocations of RunLocalUDPServerWithFinChan.
2018-09-26 09:19:35 +01:00
Tom Thorogood f195b71879 Replace unpackTxtString with identical unpackString (#751)
These two functions were identical (sans-variable names) before I
optimized unpackString in 5debfeec63.

This will improve the performance of it's only caller unpackTxt and is
covered by the test and benchmark added in 5debfeec63.
2018-09-26 09:14:19 +01:00
Tom Thorogood 94dab88533 Use correct build constraints for listen_*.go files (#750)
unix.SO_REUSEPORT isn't defined for solaris (or some other non-windows
platforms).

Fixes #747
2018-09-26 09:12:54 +01:00
Tom Thorogood 5debfeec63 Use strings.Builder in unpackString (#746)
* Add test case and benchmark for unpackString helper

* Use strings.Builder in unpackString
2018-09-23 11:21:14 +01:00
Miek Gieben f4db2ca6ed Release 1.0.10 2018-09-22 18:51:30 +01:00
tr3e 501e858f67 Fix issue #742 (#745)
* Fix error comparison in SetTA

* Add testcase TestParseTA()
2018-09-22 18:36:01 +01:00
chantra 833bf76c28 [tls] Carry TLS state within (possibly) response writer (#728)
* [tls] Carry TLS state within (possibly) response writer

This allows a server to make decision wether or not the link used to
connect to the DNS server is using TLS.
This can be used by the handler for instance to (but not limited to):
- log that the request was TLS vs TCP
- craft specific responsed knowing that the link is secured
- return custom answers based on client cert (if provided)
...

Fixes #711

* Address @tmthrgd comments:
- do not check whether w.tcp is nil
- create RR after setting txt value

* Address @miekg comments.

Attempt to make a TLS connection state specific test, it goes over
testing each individual server types (TLS, TCP, UDP) and validate that
tls.Connectionstate is only accessible when expected.

* ConnectionState() returns value instead of pointer

* * make ConnectionStater.ConnectionState() return a pointer again
* rename interface ConnectionState to ConnectionStater
* fix nits pointed by @tmthrgd

* @tmthrgd comment: Do not use concret type in `ConnectionState`
2018-09-22 18:34:55 +01:00
Miek Gieben 426ea785a9 Release 1.0.9 2018-09-15 22:43:45 +01:00
Tom Thorogood b0dc93d276
Make Shutdown wait for connections to terminate gracefully (#717)
* Make Shutdown wait for connections to terminate gracefully

* Add graceful shutdown test files from #713

* Tidy up graceful shutdown tests

* Call t.Error directly in checkInProgressQueriesAtShutdownServer

* Remove timeout arguments from RunLocal*ServerWithFinChan

* Merge defers together in (*Server).serve

This removes the defer from the UDP path, in favour of directly
calling (*sync.WaitGroup).Done after (*Serve).serveDNS has
returned.

* Replace checkInProgressQueriesAtShutdownServer implementation

This performs dialing, writing and reading as three seperate steps.

* Add sleep after writing shutdown test messages

* Avoid race condition when setting server timeouts

Server timeouts cannot be set after the server has started without
triggering the race detector. The timeout's are not strictly needed, so
remove them.

* Use a sync.Cond for testShutdownNotify

Using a chan erroneously triggered the race detector, using a sync.Cond
avoids that problem.

* Remove TestShutdownUDPWithContext

This doesn't really add anything.

* Move shutdown and conn into (*Server).init

* Only log ResponseWriter.WriteMsg error once

* Test that ShutdownContext waits for the reply

* Remove stray newline from diff

* Rename err to ctxErr in ShutdownContext

* Reword testShutdownNotify comment
2018-09-13 23:06:28 +09:30
Tom Thorogood e875a31a5c
Add SO_REUSEPORT support (#736)
* Use strings.TrimSuffix in ListenAndServe for TLS

This replaces the if/else statements with something simpler.

Interestingly, the first pull request I submitted to this library was
to fix the tcp6-tls case way back in 4744e915eb.

* Add SO_REUSEPORT implementation

Fixes #654

* Rename Reuseport field to ReusePort

* Rename supportsReuseport to match ReusePort

* Rename listenUDP and listenTCP file to listen_*.go
2018-09-10 20:12:54 +09:30
Tom Thorogood 8f0a42efa0 Fix TestServerStartStopRace calling t.Fatal on wrong goroutine (#739) 2018-09-09 20:47:16 +01:00
Tom Thorogood bfbb1715af Use ReadMsgUDP and WriteMsgUDP on windows (#738) 2018-09-08 17:33:21 +01:00
Tom Thorogood 7da8f0db5c Simplify (*Client).Dial handling of network type (#737)
* Simplify (*Client).Dial handling of network type

* Remove net.Dialer cast from (*Client).Dial
2018-09-08 17:27:21 +01:00
Tom Thorogood bf6da3a5bd Reduce UDP server memory usage (#735)
* Clear the response.msg field after unpacking

The allocated buffer cannot be freed by the garbage collector while the
response is alive, by clearing msg here, the GC can collect the buffer
sooner.

* Use a sync.Pool for UDP message buffers

* Return UDP message buffer to pool in all paths

* Move udpPool.New closure out of (*Server).init

The closure used to capture the *Server which would cause a reference
loop and prevent it from ever being released by the garbage collector.

This also gives the closure a more obvious name in memory profiles:
  github.com/miekg/dns.makeUDPBuffer.func1 rather than
  github.com/miekg/dns.(*Server).init.func1.
2018-09-08 17:15:17 +01:00
Tom Thorogood 3ce7efeace Fix Serve benchmark failures (#734)
* Fix Serve benchmark failures

At present, these benchmarks don't actually work or measure anything.
SetQuestion must have a fully qualified domain name (trailing dot) to
be valid. Because the question wasn't valid, the request never reached
the server and was rejected by the client.

With the error check added, the benchmarks started failing with:
--- FAIL: BenchmarkServe
    server_test.go:346: Exchange failed: dns: domain must be fully qualified

* Enable Serve6 benchmark

Currently this benchmark isn't run as it's not exported.

* Only enable BenchmarkServe6 when IPv6 is supported

The Serve6 benchmark has been disabled since 2014 (in 28d936c032)
because it doesn't play nice with Travis. We can just skip the benchmark
if it fails to bind to an IPv6 address.
2018-09-08 17:10:56 +01:00
Michael 9a34f54f7a Bump travis to 1.10/1.11 (#731) 2018-08-30 07:41:33 +01:00
Tom Thorogood 4bda1db839 Improve documentation of maxWorkersCount const (#726)
While I'm here, rename it to maxIdleWorkersCount so it's purpose is
clearer.

Updates #722
Updates #725
2018-08-16 17:10:20 +01:00
Alberto Bertogli 28216bf382 Add dnss to the users list (#723) 2018-08-16 17:06:07 +01:00
Tom Thorogood c9b812d1d9 Remove redundant parenthesis (#727)
* Remove redundant parenthesis

These were caught with:
    gofmt -r '(a) -> a' -w *.go

This commit only includes the changes where the formatting makes the
ordering of operations clear.

* Remove more redundant parenthesis

These were caught with:
    gofmt -r '(a) -> a' -w *.go

This commit includes the remaining changes where the formatting does not
make the ordering of operations as clear as the previous commit.
2018-08-16 17:05:27 +01:00
Tom Thorogood 208cd1e89e Simplify unlocking dance in *Serve functions (#719) 2018-08-10 22:50:48 +01:00
Olivier Poitrey 21d95e19e6 readme: add dnstrace to Users section (#721) 2018-08-10 20:17:47 +01:00
Tom Thorogood 4a8fde8d2a Add go1.10.x to Travis (#718)
tip now points to what will be go1.11 leaving go1.10 untested.
2018-08-04 08:48:20 +01:00
Tom Thorogood b559d43c31 Abstract shutdown checking into seperate function (#716) 2018-07-28 13:47:30 +01:00
Tom Thorogood 1e845a5b06 Use RFC 8032 functions added to x/crypto/ed25519 (#715)
This was added in golang/crypto@5ba7f63082 and can replace the
workaround from #458.
2018-07-25 13:01:44 +01:00
Lorenzo Fontana 8004f28488 Add testcases to validate consistency of packDataNsec (#714)
Signed-off-by: Lorenzo Fontana <lo@linux.com>
2018-07-23 22:44:09 +01:00