This function was previously changed from using strings.ToLower to a
custom loop to ensure it only lowercases ASCII characters. This was
more complicated than it needed to be and introduced more allocations
than is necessary.
Instead of that approach we call strings.Map with a simple ASCII
lowercase mapping function. Sadly we still use the nice ASCII-only fast
path that strings.ToLower had, but it's unlikely to be worth all the
extra code.
According to Section 6.2 [1] of RFC 4034,all uppercase US-ASCII letters in the
owner name of the RR are replaced by the corresponding lowercase US-ASCII
letters.
This updates CanonicalName to conform to the RFC.
[1] https://www.rfc-editor.org/rfc/rfc4034#section-6.2Fixesmiekg/dns#1434
* Improve IsFQDN performance
While this code may be slightly less clear, it's significantly faster
and this function seems to be a hot path for certain workloads.
name old time/op new time/op delta
IsFQDN/no_dot-12 5.86ns ± 2% 1.48ns ± 3% -74.71% (p=0.000 n=10+10)
IsFQDN/unescaped-12 8.73ns ± 2% 1.57ns ± 1% -81.98% (p=0.000 n=9+8)
IsFQDN/escaped-12 27.4ns ± 2% 23.8ns ± 2% -13.19% (p=0.000 n=10+10)
FQDN/is_fqdn-12 8.36ns ± 1% 1.80ns ± 2% -78.50% (p=0.000 n=9+10)
FQDN/not_fqdn-12 36.8ns ±15% 33.4ns ±12% -9.25% (p=0.035 n=10+10)
* Fixup IsFQDN comment
* Use generics for dddToByte and dddStringToByte
* Introduce generic isDDD helper
Almost all uses of isDigit look exactly the same, turn them into a
matching helper.
* add Canonical function to get name in canonical form
* replace strings.ToLower with Canonical
* rename Canonical to CanonicalName
* replace Fqdn with CanonicalName in ServeMux
* Doc updates
Was reading https://pkg.go.dev/github.com/miekg/dns?tab=doc and spotted
some types and things to could be slightly better.
Make v unexported, as this version stuff should not be part of the
public API.
Signed-off-by: Miek Gieben <miek@miek.nl>
* fix test
Signed-off-by: Miek Gieben <miek@miek.nl>
* Add a message truncation implementation
* Remove OPT if-statement at end of Scrub
* Impose RFC 6891 payload size limit in Scrub
* Remove *Msg receiver from truncateLoop
* Remove OPT record creation from Scrub
* Test that TestRequestScrubAnswerExact has correct record count
* Rename (*Msg).Scrub to Truncate
This better reflects it's purpose.
* Remove comment reference to scrubbing in Truncate
* Properly calculate the length of OPT record in Truncate
* Correct comment in IsEdns0 in regards to RFC 6891
* Handle the OPT record being anywhere in Truncate
* Slight cleanup of Msg.Truncate
* Fork packDomainName for IsDomainName
* Eliminate msg buffer from packDomainName2
* Eliminate compression code from packDomainName2
* Remove off argument and return from packDomainName2
* Remove bs buffer from packDomainName2
* Merge packDomainName2 into IsDomainName
* Eliminate root label special case from IsDomainName
* Remove ls variable from IsDomainName
* Fixup comments in IsDomainName
* Remove msg == nil special cases from packDomainName
* Eliminate lenmsg variable from packDomainName
* Eliminate label counting from packDomainName
* Change off length check in IsDomainName
* Fix IsDomainName for escaped names
* Use strings.HasSuffix for IsFqdn
* Revert "Use strings.HasSuffix for IsFqdn"
I'll submit this as a seperate PR.
This reverts commit 80bf8c8370.
* Cross reference IsDomainName and packDomainName
* Correct IsDomainName max length comment
* 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
* 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.
Start at the end of the additional section instead of the beginning.
Optionally we only scan the last 2 records, and get rid of the loop
in its entirety.
This new functions just compiles the domain to wire format, if that
works, the name is deemed OK. It is also much less strict than the
older code. Almost everything is allowed in the name, except two
dots back to back (there is an explicit test for that).