* ZoneParser: error on parsing an IPv6 address in an A record
And vice versa for IPv4 with AAAA.
The implementation of isIPv6 is inspired by e341bae08d/src/net/ip.go (L678-L681) .
* Fix benchmarks that try to use ::1 as A record.
* Test A/AAAA parsing via NewRR rather than zone parser.
* Document why we distinguish IPv4 vs IPv6 via existence of ":".
* Reduce compression memory use with map[string]uint16
map[string]uint16 uses 25% less memory per-entry than a map[string]int
(16+2)/(16+8) = 0.75. All entries in the compression map are bound by
maxCompressionOffset which is 14-bits and fits within a uint16.
* Add PackMsg benchmark with more RRs
* Add a comment to the compressionMap struct
* Fix compressed length calculations for escaped names
* Add Len benchmark for escaped name
* Fix length with escaping after compression point
* Avoid calling escapedNameLen multiple times in domainNameLen
* Use regular quotes for question in TestMsgCompressLengthEscaped
* Remove fullSize return from compressionLenSearch
This wasn't used anywhere but TestCompressionLenSearch, and was very
wrong.
* Add generated compressedLen functions and use them
This replaces the confusing and complicated compressionLenSlice
function.
* Use compressedLenWithCompressionMap even for uncompressed
This leaves the len() functions unused and they'll soon be removed.
This also fixes the off-by-one error of compressedLen when a (Q)NAME
is ".".
* Use Len helper instead of RR.len private method
* Merge len and compressedLen functions
* Merge compressedLen helper into Msg.Len
* Remove compress bool from compressedLenWithCompressionMap
* Merge map insertion into compressionLenSearch
This eliminates the need to loop over the domain name twice when we're
compressing the name.
* Use compressedNameLen for NSEC.NextDomain
This was a mistake.
* Remove compress from RR.len
* Add test case for multiple questions length
* Add test case for MINFO and SOA compression
These are the only RRs with multiple compressible names within the same
RR, and they were previously broken.
* Rename compressedNameLen to domainNameLen
It also handles the length of uncompressed domain names.
* Use off directly instead of len(s[:off])
* Move initial maxCompressionOffset check out of compressionLenMapInsert
This should allow us to avoid the call overhead of
compressionLenMapInsert in certain limited cases and may result in a
slight performance increase.
compressionLenMapInsert still has a maxCompressionOffset check inside
the for loop.
* Rename compressedLenWithCompressionMap to msgLenWithCompressionMap
This better reflects that it also calculates the uncompressed length.
* Merge TestMsgCompressMINFO with TestMsgCompressSOA
They're both testing the same thing.
* Remove compressionLenMapInsert
compressionLenSearch does everything compressionLenMapInsert did anyway.
* Only call compressionLenSearch in one place in domainNameLen
* Split if statement in domainNameLen
The last two commits worsened the performance of domainNameLen
noticably, this change restores it's original performance.
name old time/op new time/op delta
MsgLength-12 550ns ±13% 510ns ±21% ~ (p=0.050 n=10+10)
MsgLengthNoCompression-12 26.9ns ± 2% 27.0ns ± 1% ~ (p=0.198 n=9+10)
MsgLengthPack-12 2.30µs ±12% 2.26µs ±16% ~ (p=0.739 n=10+10)
MsgLengthMassive-12 32.9µs ± 7% 32.0µs ±10% ~ (p=0.243 n=9+10)
MsgLengthOnlyQuestion-12 9.60ns ± 1% 9.20ns ± 1% -4.16% (p=0.000 n=9+9)
* Remove stray newline from TestMsgCompressionMultipleQuestions
* Remove stray newline in length_test.go
This was introduced when resolving merge conflicts.
* Reduce allocations in UnpackDomainName by better sizing slice
The maximum size of a domain name in presentation format is bounded by
the maximum length of a name in wire octet form and the maximum length
of a label. As s doesn't escape from UnpackDomainName, we can safely
give it the maximum capacity and it will never need to grow.
* Benchmark UnpackDomainName with lonest names possible
* Rename BenchmarkUnpackDomainNameLongestEscaped to match
* Improve maxDomainNamePresentationLength comment
* Further improve maxDomainNamePresentationLength comment
* Use map[string]struct{} for compression map in Len
map[string]int requires 8 bytes per entry to store the unused position
information.
* Add MsgLength benchmark with more RRs
* Pass dns.Compress explicitly to packBufferWithCompressionMap
* Avoid creating compression map for question only Msg
This idea was inspired by:
"Skip dname compression for replies with no answers."
https://www.nlnetlabs.nl/bugs-script/show_bug.cgi?id=235
* Continue compressing multiple questions
Use :0 for loopback testing. This is more portable between testing environments.
Add testRR that calls NewRR and throws error away - apply it everywhere where needed.
It seems only Go 1.9 can deal with :0 being used. Disable 1.8 in travis.
* Use crypto/rand to seed math/rand instead of using the default seed
* Better seeding+generation and fallback on crypto/rand.Read failure
* Remove user warning
Remove the use of reflection when packing and unpacking, instead
generate all the pack and unpack functions using msg_generate.
This will generate zmsg.go which in turn calls the helper functions from
msg_helper.go.
This increases the speed by about ~30% while cutting back on memory
usage. Not all RRs are using it, but that will be rectified in upcoming
PR.
Most of the speed increase is in the header/question section parsing.
These functions *are* not generated, but straight forward enough. The
implementation can be found in msg.go.
The new code has been fuzzed by go-fuzz, which turned up some issues.
All files that started with 'z', and not autogenerated were renamed,
i.e. zscan.go is now scan.go.
Reflection is still used, in subsequent PRs it will be removed entirely.