Commit Graph

12 Commits

Author SHA1 Message Date
Tom F 487e4636d5 ZoneParser: error on parsing an IPv6 address in an A record (#923)
* 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 ":".
2019-03-09 09:02:18 +00:00
Tom Thorogood b0835fab5e Reduce allocations in ReverseAddr (#872)
* Add ReverseAddr benchmarks

* Eliminate buffer allocation in ReverseAddr for v6

When the size of a slice is constant it can be allocated on the stack
rather than the heap.

name                old time/op    new time/op    delta
ReverseAddr/IP4-12     175ns ± 5%     173ns ± 4%     ~     (p=0.323 n=10+10)
ReverseAddr/IP6-12     364ns ±14%     218ns ±24%  -40.12%  (p=0.000 n=10+10)

name                old alloc/op   new alloc/op   delta
ReverseAddr/IP4-12     51.0B ± 0%     51.0B ± 0%     ~     (all equal)
ReverseAddr/IP6-12      176B ± 0%       96B ± 0%  -45.45%  (p=0.000 n=10+10)

name                old allocs/op  new allocs/op  delta
ReverseAddr/IP4-12      3.00 ± 0%      3.00 ± 0%     ~     (all equal)
ReverseAddr/IP6-12      3.00 ± 0%      2.00 ± 0%  -33.33%  (p=0.000 n=10+10)

* Reduce allocations in ReverseAddr for v4

name                old time/op    new time/op    delta
ReverseAddr/IP4-12     173ns ± 4%     140ns ±13%  -18.97%  (p=0.000 n=10+10)
ReverseAddr/IP6-12     218ns ±24%     218ns ±22%     ~     (p=0.838 n=10+10)

name                old alloc/op   new alloc/op   delta
ReverseAddr/IP4-12     51.0B ± 0%     48.0B ± 0%   -5.88%  (p=0.000 n=10+10)
ReverseAddr/IP6-12     96.0B ± 0%     96.0B ± 0%     ~     (all equal)

name                old allocs/op  new allocs/op  delta
ReverseAddr/IP4-12      3.00 ± 0%      2.00 ± 0%  -33.33%  (p=0.000 n=10+10)
ReverseAddr/IP6-12      2.00 ± 0%      2.00 ± 0%     ~     (all equal)

* Compare returned address in BenchmarkReverseAddr
2018-12-30 10:28:48 +00:00
Tom Thorogood 470f08e191
Reduce compression memory use with map[string]uint16 (#852)
* 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
2018-12-02 08:50:51 +10:30
Tom Thorogood 8d24af5fb5 Fix compressed length calculations for escaped names (#850)
* 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
2018-11-30 07:50:49 +00:00
Tom Thorogood 778aa4f83d
Properly calculate compressed message lengths (#833)
* 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.
2018-11-30 10:03:41 +10:30
Tom Thorogood c0747f060e Reduce allocations in UnpackDomainName by better sizing slice (#844)
* 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
2018-11-29 19:55:51 +00:00
Tom Thorogood 7ae05cdcf8
Use map[string]struct{} for compression map in Len (#820)
* 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
2018-11-28 08:02:08 +10:30
Tom Thorogood e2f69345fd Avoid creating compression map for question only Msg (#823)
* 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
2018-11-27 14:34:07 +00:00
Miek Gieben 388f6eea29
Tests updates (#556)
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.
2017-11-08 10:01:19 +00:00
Tom Thorogood 5f64fb22f9 Simplify compressed length code (#527)
* Add BenchmarkMsgLengthNoCompression

* Simplify compressedLen loops

* Fix typo in compressionLenSlice
2017-10-13 17:21:12 +02:00
Roland Bracewell Shoemaker 3f53d75269 Seed math/rand with crypto/rand (#359)
* 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
2016-06-05 07:51:30 +01:00
Miek Gieben 475ab80867 Remove (most) reflection
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.
2016-06-03 12:45:22 +01:00