From 4fbd7abb5735c1f26e8e77d12827682c5c2f36fa Mon Sep 17 00:00:00 2001 From: Mechiel Lukkien Date: Fri, 8 Mar 2024 15:31:54 +0100 Subject: [PATCH] update to latest adns, synced with Go's net --- go.mod | 2 +- go.sum | 4 +- vendor/github.com/mjl-/adns/conf.go | 13 +--- vendor/github.com/mjl-/adns/dial.go | 4 +- vendor/github.com/mjl-/adns/dnsclient_unix.go | 74 +++++++++++++------ vendor/github.com/mjl-/adns/hook.go | 3 +- vendor/github.com/mjl-/adns/hook_plan9.go | 9 +++ vendor/github.com/mjl-/adns/hook_unix.go | 11 +++ vendor/github.com/mjl-/adns/hook_windows.go | 18 +++++ vendor/github.com/mjl-/adns/hosts.go | 2 +- .../adns/internal/bytealg/count_generic.go | 25 +++++++ .../internal/bytealg/lastindexbyte_generic.go | 23 ++++++ vendor/github.com/mjl-/adns/ipsock.go | 4 +- vendor/github.com/mjl-/adns/lookup.go | 50 ++++++++----- vendor/github.com/mjl-/adns/net.go | 6 +- vendor/github.com/mjl-/adns/parse.go | 22 ------ vendor/modules.txt | 2 +- 17 files changed, 187 insertions(+), 85 deletions(-) create mode 100644 vendor/github.com/mjl-/adns/hook_plan9.go create mode 100644 vendor/github.com/mjl-/adns/hook_unix.go create mode 100644 vendor/github.com/mjl-/adns/hook_windows.go create mode 100644 vendor/github.com/mjl-/adns/internal/bytealg/count_generic.go create mode 100644 vendor/github.com/mjl-/adns/internal/bytealg/lastindexbyte_generic.go diff --git a/go.mod b/go.mod index a454045..16a10a1 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/mjl-/mox go 1.21 require ( - github.com/mjl-/adns v0.0.0-20231109160910-82839fe3e6ae + github.com/mjl-/adns v0.0.0-20240308133139-6bfb89c3f854 github.com/mjl-/autocert v0.0.0-20231214125928-31b7400acb05 github.com/mjl-/bstore v0.0.4 github.com/mjl-/sconf v0.0.5 diff --git a/go.sum b/go.sum index 31514cc..1d8cfbd 100644 --- a/go.sum +++ b/go.sum @@ -24,8 +24,8 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= -github.com/mjl-/adns v0.0.0-20231109160910-82839fe3e6ae h1:P/kTaQbDFSbmDK+RVjwu7mPyr6a6XyHqHu1PlRMEbAU= -github.com/mjl-/adns v0.0.0-20231109160910-82839fe3e6ae/go.mod h1:v47qUMJnipnmDTRGaHwpCwzE6oypa5K33mUvBfzZBn8= +github.com/mjl-/adns v0.0.0-20240308133139-6bfb89c3f854 h1:BeYqeRkulstKKKCdzk7IOYNeuJPhqmLnaMhu69GxQUs= +github.com/mjl-/adns v0.0.0-20240308133139-6bfb89c3f854/go.mod h1:v47qUMJnipnmDTRGaHwpCwzE6oypa5K33mUvBfzZBn8= github.com/mjl-/autocert v0.0.0-20231214125928-31b7400acb05 h1:s6ay4bh4tmpPLdxjyeWG45mcwHfEluBMuGPkqxHWUJ4= github.com/mjl-/autocert v0.0.0-20231214125928-31b7400acb05/go.mod h1:taMFU86abMxKLPV4Bynhv8enbYmS67b8LG80qZv2Qus= github.com/mjl-/bstore v0.0.4 h1:q+R1oAr8+E9yf9q+zxkVjQ18VFqD/E9KmGVoe4FIOBA= diff --git a/vendor/github.com/mjl-/adns/conf.go b/vendor/github.com/mjl-/adns/conf.go index d9679c0..b8ae568 100644 --- a/vendor/github.com/mjl-/adns/conf.go +++ b/vendor/github.com/mjl-/adns/conf.go @@ -157,7 +157,7 @@ func initConfVal() { } } -// goosPreferCgo reports whether the GOOS value passed in prefers +// goosPrefersCgo reports whether the GOOS value passed in prefers // the cgo resolver. func goosPrefersCgo() bool { switch runtime.GOOS { @@ -225,16 +225,7 @@ func (c *conf) lookupOrder(r *Resolver, hostname string) (ret hostLookupOrder, d // Go resolver was explicitly requested // or cgo resolver is not available. // Figure out the order below. - switch c.goos { - case "windows": - // TODO(bradfitz): implement files-based - // lookup on Windows too? I guess /etc/hosts - // kinda exists on Windows. But for now, only - // do DNS. - fallbackOrder = hostLookupDNS - default: - fallbackOrder = hostLookupFilesDNS - } + fallbackOrder = hostLookupFilesDNS canUseCgo = false } else if c.netCgo { // Cgo resolver was explicitly requested. diff --git a/vendor/github.com/mjl-/adns/dial.go b/vendor/github.com/mjl-/adns/dial.go index 115e8e4..4ca2bfc 100644 --- a/vendor/github.com/mjl-/adns/dial.go +++ b/vendor/github.com/mjl-/adns/dial.go @@ -7,10 +7,12 @@ package adns import ( "context" "net" + + "github.com/mjl-/adns/internal/bytealg" ) func parseNetwork(ctx context.Context, network string, needsProto bool) (afnet string, proto int, err error) { - i := last(network, ':') + i := bytealg.LastIndexByteString(network, ':') if i < 0 { // no colon switch network { case "tcp", "tcp4", "tcp6": diff --git a/vendor/github.com/mjl-/adns/dnsclient_unix.go b/vendor/github.com/mjl-/adns/dnsclient_unix.go index 4dbfb00..b436ad1 100644 --- a/vendor/github.com/mjl-/adns/dnsclient_unix.go +++ b/vendor/github.com/mjl-/adns/dnsclient_unix.go @@ -29,6 +29,7 @@ import ( "golang.org/x/net/dns/dnsmessage" + "github.com/mjl-/adns/internal/bytealg" "github.com/mjl-/adns/internal/itoa" ) @@ -205,7 +206,14 @@ func (r *Resolver) exchange(ctx context.Context, server string, q dnsmessage.Que if err := p.SkipQuestion(); err != dnsmessage.ErrSectionDone { return dnsmessage.Parser{}, dnsmessage.Header{}, errInvalidDNSResponse } - if h.Truncated { // see RFC 5966 + // RFC 5966 indicates that when a client receives a UDP response with + // the TC flag set, it should take the TC flag as an indication that it + // should retry over TCP instead. + // The case when the TC flag is set in a TCP response is not well specified, + // so this implements the glibc resolver behavior, returning the existing + // dns response instead of returning a "errNoAnswerFromDNSServer" error. + // See go.dev/issue/64896 + if h.Truncated && network == "udp" { continue } return p, h, nil @@ -215,7 +223,9 @@ func (r *Resolver) exchange(ctx context.Context, server string, q dnsmessage.Que // checkHeader performs basic sanity checks on the header. func checkHeader(p *dnsmessage.Parser, h dnsmessage.Header) error { - if h.RCode == dnsmessage.RCodeNameError { + rcode, hasAdd := extractExtendedRCode(*p, h) + + if rcode == dnsmessage.RCodeNameError { return errNoSuchHost } @@ -226,17 +236,17 @@ func checkHeader(p *dnsmessage.Parser, h dnsmessage.Header) error { // libresolv continues to the next server when it receives // an invalid referral response. See golang.org/issue/15434. - if h.RCode == dnsmessage.RCodeSuccess && !h.Authoritative && !h.RecursionAvailable && err == dnsmessage.ErrSectionDone { + if rcode == dnsmessage.RCodeSuccess && !h.Authoritative && !h.RecursionAvailable && err == dnsmessage.ErrSectionDone && !hasAdd { return errLameReferral } - if h.RCode != dnsmessage.RCodeSuccess && h.RCode != dnsmessage.RCodeNameError { + if rcode != dnsmessage.RCodeSuccess && h.RCode != dnsmessage.RCodeNameError { // None of the error codes make sense // for the query we sent. If we didn't get // a name error and we didn't get success, // the server is behaving incorrectly or // having temporary trouble. - if h.RCode == dnsmessage.RCodeServerFailure { + if rcode == dnsmessage.RCodeServerFailure { // Look for Extended DNS Error (EDE), RFC 8914. if p.SkipAllAnswers() != nil || p.SkipAllAuthorities() != nil { @@ -302,6 +312,26 @@ func skipToAnswer(p *dnsmessage.Parser, qtype dnsmessage.Type) error { } } +// extractExtendedRCode extracts the extended RCode from the OPT resource (EDNS(0)) +// If an OPT record is not found, the RCode from the hdr is returned. +// Another return value indicates whether an additional resource was found. +func extractExtendedRCode(p dnsmessage.Parser, hdr dnsmessage.Header) (dnsmessage.RCode, bool) { + p.SkipAllAnswers() + p.SkipAllAuthorities() + hasAdd := false + for { + ahdr, err := p.AdditionalHeader() + if err != nil { + return hdr.RCode, hasAdd + } + hasAdd = true + if ahdr.Type == dnsmessage.TypeOPT { + return ahdr.ExtendedRCode(hdr.RCode), hasAdd + } + p.SkipAdditional() + } +} + // Do a lookup for a single name, which must be rooted // (otherwise answer will not find the answers). func (r *Resolver) tryOneName(ctx context.Context, cfg *dnsConfig, name string, qtype dnsmessage.Type) (dnsmessage.Parser, string, Result, error) { @@ -542,10 +572,6 @@ func avoidDNS(name string) bool { // nameList returns a list of names for sequential DNS queries. func (conf *dnsConfig) nameList(name string) []string { - if avoidDNS(name) { - return nil - } - // Check name length (see isDomainName). l := len(name) rooted := l > 0 && name[l-1] == '.' @@ -555,27 +581,31 @@ func (conf *dnsConfig) nameList(name string) []string { // If name is rooted (trailing dot), try only that name. if rooted { + if avoidDNS(name) { + return nil + } return []string{name} } - hasNdots := count(name, '.') >= conf.ndots + hasNdots := bytealg.CountString(name, '.') >= conf.ndots name += "." l++ // Build list of search choices. names := make([]string, 0, 1+len(conf.search)) // If name has enough dots, try unsuffixed first. - if hasNdots { + if hasNdots && !avoidDNS(name) { names = append(names, name) } // Try suffixes that are not too long (see isDomainName). for _, suffix := range conf.search { - if l+len(suffix) <= 254 { - names = append(names, name+suffix) + fqdn := name + suffix + if !avoidDNS(fqdn) && len(fqdn) <= 254 { + names = append(names, fqdn) } } // Try unsuffixed, if not tried first above. - if !hasNdots { + if !hasNdots && !avoidDNS(name) { names = append(names, name) } return names @@ -767,7 +797,7 @@ func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, network, name strin h, err := result0.p.AnswerHeader() if err != nil && err != dnsmessage.ErrSectionDone { lastErr = &DNSError{ - Err: "cannot marshal DNS message", + Err: errCannotUnmarshalDNSMessage.Error(), Name: name, Server: result0.server, } @@ -780,7 +810,7 @@ func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, network, name strin a, err := result0.p.AResource() if err != nil { lastErr = &DNSError{ - Err: "cannot marshal DNS message", + Err: errCannotUnmarshalDNSMessage.Error(), Name: name, Server: result0.server, } @@ -795,7 +825,7 @@ func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, network, name strin aaaa, err := result0.p.AAAAResource() if err != nil { lastErr = &DNSError{ - Err: "cannot marshal DNS message", + Err: errCannotUnmarshalDNSMessage.Error(), Name: name, Server: result0.server, } @@ -810,7 +840,7 @@ func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, network, name strin c, err := result0.p.CNAMEResource() if err != nil { lastErr = &DNSError{ - Err: "cannot marshal DNS message", + Err: errCannotUnmarshalDNSMessage.Error(), Name: name, Server: result0.server, } @@ -823,7 +853,7 @@ func (r *Resolver) goLookupIPCNAMEOrder(ctx context.Context, network, name strin default: if err := result0.p.SkipAnswer(); err != nil { lastErr = &DNSError{ - Err: "cannot marshal DNS message", + Err: errCannotUnmarshalDNSMessage.Error(), Name: name, Server: result0.server, } @@ -915,7 +945,7 @@ func (r *Resolver) goLookupPTR(ctx context.Context, addr string, order hostLooku } if err != nil { return nil, result, &DNSError{ - Err: "cannot marshal DNS message", + Err: errCannotUnmarshalDNSMessage.Error(), Name: addr, Server: server, } @@ -924,7 +954,7 @@ func (r *Resolver) goLookupPTR(ctx context.Context, addr string, order hostLooku err := p.SkipAnswer() if err != nil { return nil, result, &DNSError{ - Err: "cannot marshal DNS message", + Err: errCannotUnmarshalDNSMessage.Error(), Name: addr, Server: server, } @@ -934,7 +964,7 @@ func (r *Resolver) goLookupPTR(ctx context.Context, addr string, order hostLooku ptr, err := p.PTRResource() if err != nil { return nil, result, &DNSError{ - Err: "cannot marshal DNS message", + Err: errCannotUnmarshalDNSMessage.Error(), Name: addr, Server: server, } diff --git a/vendor/github.com/mjl-/adns/hook.go b/vendor/github.com/mjl-/adns/hook.go index 4c49fcc..132c54b 100644 --- a/vendor/github.com/mjl-/adns/hook.go +++ b/vendor/github.com/mjl-/adns/hook.go @@ -10,8 +10,7 @@ import ( ) var ( - testHookHostsPath = "/etc/hosts" - testHookLookupIP = func( + testHookLookupIP = func( ctx context.Context, fn func(context.Context, string, string) ([]net.IPAddr, Result, error), network string, diff --git a/vendor/github.com/mjl-/adns/hook_plan9.go b/vendor/github.com/mjl-/adns/hook_plan9.go new file mode 100644 index 0000000..6020d32 --- /dev/null +++ b/vendor/github.com/mjl-/adns/hook_plan9.go @@ -0,0 +1,9 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package net + +var ( + hostsFilePath = "/etc/hosts" +) diff --git a/vendor/github.com/mjl-/adns/hook_unix.go b/vendor/github.com/mjl-/adns/hook_unix.go new file mode 100644 index 0000000..3947c64 --- /dev/null +++ b/vendor/github.com/mjl-/adns/hook_unix.go @@ -0,0 +1,11 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build unix || js || wasip1 + +package adns + +var ( + hostsFilePath = "/etc/hosts" +) diff --git a/vendor/github.com/mjl-/adns/hook_windows.go b/vendor/github.com/mjl-/adns/hook_windows.go new file mode 100644 index 0000000..5d2b92a --- /dev/null +++ b/vendor/github.com/mjl-/adns/hook_windows.go @@ -0,0 +1,18 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package adns + +import ( + "golang.org/x/sys/windows" +) + +func windowsGetSystemDirectory() string { + p, _ := windows.GetSystemDirectory() + return p +} + +var ( + hostsFilePath = windowsGetSystemDirectory() + "/Drivers/etc/hosts" +) diff --git a/vendor/github.com/mjl-/adns/hosts.go b/vendor/github.com/mjl-/adns/hosts.go index c81cac9..19f8ca6 100644 --- a/vendor/github.com/mjl-/adns/hosts.go +++ b/vendor/github.com/mjl-/adns/hosts.go @@ -52,7 +52,7 @@ var hosts struct { func readHosts() { now := time.Now() - hp := testHookHostsPath + hp := hostsFilePath if now.Before(hosts.expire) && hosts.path == hp && len(hosts.byName) > 0 { return diff --git a/vendor/github.com/mjl-/adns/internal/bytealg/count_generic.go b/vendor/github.com/mjl-/adns/internal/bytealg/count_generic.go new file mode 100644 index 0000000..de08418 --- /dev/null +++ b/vendor/github.com/mjl-/adns/internal/bytealg/count_generic.go @@ -0,0 +1,25 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bytealg + +func Count(b []byte, c byte) int { + n := 0 + for _, x := range b { + if x == c { + n++ + } + } + return n +} + +func CountString(s string, c byte) int { + n := 0 + for i := 0; i < len(s); i++ { + if s[i] == c { + n++ + } + } + return n +} diff --git a/vendor/github.com/mjl-/adns/internal/bytealg/lastindexbyte_generic.go b/vendor/github.com/mjl-/adns/internal/bytealg/lastindexbyte_generic.go new file mode 100644 index 0000000..b905f53 --- /dev/null +++ b/vendor/github.com/mjl-/adns/internal/bytealg/lastindexbyte_generic.go @@ -0,0 +1,23 @@ +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bytealg + +func LastIndexByte(s []byte, c byte) int { + for i := len(s) - 1; i >= 0; i-- { + if s[i] == c { + return i + } + } + return -1 +} + +func LastIndexByteString(s string, c byte) int { + for i := len(s) - 1; i >= 0; i-- { + if s[i] == c { + return i + } + } + return -1 +} diff --git a/vendor/github.com/mjl-/adns/ipsock.go b/vendor/github.com/mjl-/adns/ipsock.go index 87d75c1..35a011c 100644 --- a/vendor/github.com/mjl-/adns/ipsock.go +++ b/vendor/github.com/mjl-/adns/ipsock.go @@ -68,7 +68,7 @@ func SplitHostPort(hostport string) (host, port string, err error) { j, k := 0, 0 // The port starts after the last colon. - i := last(hostport, ':') + i := bytealg.LastIndexByteString(hostport, ':') if i < 0 { return addrErr(hostport, missingPort) } @@ -115,7 +115,7 @@ func SplitHostPort(hostport string) (host, port string, err error) { func splitHostZone(s string) (host, zone string) { // The IPv6 scoped addressing zone identifier starts after the // last percent sign. - if i := last(s, '%'); i > 0 { + if i := bytealg.LastIndexByteString(s, '%'); i > 0 { host, zone = s[:i], s[i+1:] } else { host = s diff --git a/vendor/github.com/mjl-/adns/lookup.go b/vendor/github.com/mjl-/adns/lookup.go index 4ff320c..66f1dc2 100644 --- a/vendor/github.com/mjl-/adns/lookup.go +++ b/vendor/github.com/mjl-/adns/lookup.go @@ -42,19 +42,20 @@ var services = map[string]map[string]int{ "domain": 53, }, "tcp": { - "ftp": 21, - "ftps": 990, - "gopher": 70, // ʕ◔ϖ◔ʔ - "http": 80, - "https": 443, - "imap2": 143, - "imap3": 220, - "imaps": 993, - "pop3": 110, - "pop3s": 995, - "smtp": 25, - "ssh": 22, - "telnet": 23, + "ftp": 21, + "ftps": 990, + "gopher": 70, // ʕ◔ϖ◔ʔ + "http": 80, + "https": 443, + "imap2": 143, + "imap3": 220, + "imaps": 993, + "pop3": 110, + "pop3s": 995, + "smtp": 25, + "submissions": 465, + "ssh": 22, + "telnet": 23, }, } @@ -84,12 +85,20 @@ const maxPortBufSize = len("mobility-header") + 10 func lookupPortMap(network, service string) (port int, error error) { switch network { - case "tcp4", "tcp6": - network = "tcp" - case "udp4", "udp6": - network = "udp" + case "ip": // no hints + if p, err := lookupPortMapWithNetwork("tcp", "ip", service); err == nil { + return p, nil + } + return lookupPortMapWithNetwork("udp", "ip", service) + case "tcp", "tcp4", "tcp6": + return lookupPortMapWithNetwork("tcp", "tcp", service) + case "udp", "udp4", "udp6": + return lookupPortMapWithNetwork("udp", "udp", service) } + return 0, &DNSError{Err: "unknown network", Name: network + "/" + service} +} +func lookupPortMapWithNetwork(network, errNetwork, service string) (port int, error error) { if m, ok := services[network]; ok { var lowerService [maxPortBufSize]byte n := copy(lowerService[:], service) @@ -97,8 +106,9 @@ func lookupPortMap(network, service string) (port int, error error) { if port, ok := m[string(lowerService[:n])]; ok && n == len(service) { return port, nil } + return 0, &DNSError{Err: "unknown port", Name: errNetwork + "/" + service, IsNotFound: true} } - return 0, &net.AddrError{Err: "unknown port", Addr: network + "/" + service} + return 0, &DNSError{Err: "unknown network", Name: errNetwork + "/" + service} } // ipVersion returns the provided network's IP version: '4', '6' or 0 @@ -399,11 +409,13 @@ func LookupPort(network, service string) (port int, err error) { } // LookupPort looks up the port for the given network and service. +// +// The network must be one of "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6" or "ip". func (r *Resolver) LookupPort(ctx context.Context, network, service string) (port int, err error) { port, needsLookup := parsePort(service) if needsLookup { switch network { - case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6": + case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6", "ip": case "": // a hint wildcard for Go 1.0 undocumented behavior network = "ip" default: diff --git a/vendor/github.com/mjl-/adns/net.go b/vendor/github.com/mjl-/adns/net.go index d586a5f..6e9bc29 100644 --- a/vendor/github.com/mjl-/adns/net.go +++ b/vendor/github.com/mjl-/adns/net.go @@ -79,7 +79,11 @@ type DNSError struct { Server string // server used IsTimeout bool // if true, timed out; not all timeouts set this IsTemporary bool // if true, error is temporary; not all errors set this - IsNotFound bool // if true, host could not be found + + // IsNotFound is set to true when the requested name does not + // contain any records of the requested type (data not found), + // or the name itself was not found (NXDOMAIN). + IsNotFound bool } // Unwrap returns the underlying error, which could be an ExtendedError. diff --git a/vendor/github.com/mjl-/adns/parse.go b/vendor/github.com/mjl-/adns/parse.go index ad3d6c8..1402356 100644 --- a/vendor/github.com/mjl-/adns/parse.go +++ b/vendor/github.com/mjl-/adns/parse.go @@ -142,28 +142,6 @@ func dtoi(s string) (n int, i int, ok bool) { return n, i, true } -// Number of occurrences of b in s. -func count(s string, b byte) int { - n := 0 - for i := 0; i < len(s); i++ { - if s[i] == b { - n++ - } - } - return n -} - -// Index of rightmost occurrence of b in s. -func last(s string, b byte) int { - i := len(s) - for i--; i >= 0; i-- { - if s[i] == b { - break - } - } - return i -} - // hasUpperCase tells whether the given string contains at least one upper-case. func hasUpperCase(s string) bool { for i := range s { diff --git a/vendor/modules.txt b/vendor/modules.txt index b199d62..56f94ed 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -7,7 +7,7 @@ github.com/cespare/xxhash/v2 # github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 ## explicit; go 1.19 github.com/matttproud/golang_protobuf_extensions/v2/pbutil -# github.com/mjl-/adns v0.0.0-20231109160910-82839fe3e6ae +# github.com/mjl-/adns v0.0.0-20240308133139-6bfb89c3f854 ## explicit; go 1.20 github.com/mjl-/adns github.com/mjl-/adns/internal/bytealg