- Check domain name availability using Domainr's JSON API.
domainr / dnsr Goto Github PK
View Code? Open in Web Editor NEWIterative DNS resolver for Go (golang).
License: MIT License
Iterative DNS resolver for Go (golang).
License: MIT License
I'm hitting an issue due to the IP version split. Trying to query for both versions can lead to a network exchange on every resolution.
What would you guys think about supporting multitype queries? Behavior would be: First check cache for all the types. Only hit the network if we have none of them. Short circuit at the soonest point so you do the minimum network exchange. This is currently not possible externally, since cache is inaccessible.
Motivation is the common situation where a server only has an IPv4 address. You'd like to query for v6 but if you get v4 stick with it. So you don't keep hitting the network on every resolution.
rrs := resolver.ResolveAlternate("example.com", []string{"AAAA", "A"})
bookmoons/resolve-alternate
has a working implementation.
Analagous logic with the current version that hits network every time:
example.com. IN A 192.0.2.1
func resolveIP() {
ipv6s := resolver.Resolve("example.com", "AAAA")
if len(ipv6s) > 0 {
return ipv6s
}
ipv4s := resolver.Resolve("example.com", "A")
if len(ipv4s) > 0 {
// Cache for type A only hit after network query for AAAA
return ipv4s
}
return emptyRRs
}
We currently set 5s timeouts for each stage of a DNS request (connect, write, read) at 5s, which results in an unpredictable upper bound on latency. We would like to set an absolute upper boundfor latency at 5s, which should be straightforward to achieve with a network deadline on the client.
Looks like the tests are failing, after I merged #47.
Lines 124 to 127 in 5293a1c
Such as xxxxx.sn.mynetname.net
which is used for RouterBoard DDNS function (xxxxx is a random serial number on RouterBoard), the resolver trying to resolve a NS Record sn.mynetname.net
, but the domain was stored on mynetname.net
, and it received a NXDOMAIN response then return nil, it should try until the server mynetname.net
also response an error
Per our discussion yesterday:
I'm getting a nil panic from this line:
Line 374 in aa0c407
Full trace
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x1066173]
goroutine 22668 [running]:
github.com/domainr/dnsr.(*Resolver).exchangeIP(0xc0011de090, {0x481cb28, 0xc003b10c30}, {0xc0055ffa28, 0x13}, {0xc01925a140, 0xe}, {0xc0055ff668, 0x12}, {0x1f3bc0a, ...}, ...)
/root/.cache/go-build/github.com/domainr/[email protected]/resolver.go:374 +0x6b3
github.com/domainr/dnsr.(*Resolver).exchange(0xc0011de090, {0x481cb28, 0xc003b10c30}, {0xc0055ffa28, 0x13}, {0xc0055ff668, 0x12}, {0x1f3bc0a, 0x3}, 0x1)
/root/.cache/go-build/github.com/domainr/[email protected]/resolver.go:294 +0x185
github.com/domainr/dnsr.(*Resolver).iterateParents.func1({0xc0055ffa28?, 0xc001f8aa20?})
/root/.cache/go-build/github.com/domainr/[email protected]/resolver.go:235 +0x89
created by github.com/domainr/dnsr.(*Resolver).iterateParents in goroutine 19692
/root/.cache/go-build/github.com/domainr/[email protected]/resolver.go:234 +0x9ae
I've not managed to reliably reproduce it but I'm reasonably sure the bug comes from these lines
Lines 354 to 359 in aa0c407
The err
return from client.ExchangeWithConnContext
is never checked because it's been shadowed by line 354
This means that resolvers with dnsr.WithTCPRetry()
can panic if:
In this case, the error check is ineffective at guarding against nil rmsg
values because the error from the TCP lookup has been lost to the shadowed err
var
Lines 369 to 371 in aa0c407
First off great lib, okay so when I do resolver.ResolveCtx(ctx, "google.com.", "TXT")
I get 6 TXT records:
Resolver settings:
var resolver *dnsr.Resolver = dnsr.NewResolver(dnsr.WithTimeout(5*time.Second), dnsr.WithCache(10000), dnsr.WithExpiry())
==================== Test output for //ogcode/services/certificate-bot/lib/resolver:resolver_test:
╭─── resolve("google.com.", "TXT", 1)
│ ╭─── resolve("google.com.", "NS", 2)
│ │ ╭─── resolve("com.", "NS", 3)
X 29ms (T- 4999ms): dig +norecurse @b.root-servers.net. com. NS # rmsg: NOERROR Answer: 0 NS: 13 Extra: 12 == CANCELED ==
X 26ms (T- 4990ms): dig +norecurse @a.gtld-servers.net. one.com. NS # rmsg: NOERROR Answer: 0 NS: 2 Extra: 0 == CANCELED ==
│ │ │ 9ms (T- 4999ms): dig +norecurse @e.root-servers.net. com. NS # rmsg: NOERROR Answer: 0 NS: 13 Extra: 15
│ │ ╰─── 9ms: resolve("com.", "NS", 3) # [26]RR = NS(com.)=a.gtld-servers.net. NS(com.)=b.gtld-servers.net. ...
│ │ 7ms (T- 4990ms): dig +norecurse @b.gtld-servers.net. google.com. NS # rmsg: NOERROR Answer: 0 NS: 4 Extra: 8
│ ╰─── 17ms: resolve("google.com.", "NS", 2) # [8]RR = NS(google.com.)=ns2.google.com. NS(google.com.)=ns1.google.com. ...
X 29ms (T- 4999ms): dig +norecurse @b.root-servers.net. com. NS # rmsg: NOERROR Answer: 0 NS: 13 Extra: 12 == CANCELED ==
X 26ms (T- 4990ms): dig +norecurse @a.gtld-servers.net. google.com. NS # rmsg: NOERROR Answer: 0 NS: 4 Extra: 8 == CANCELED ==
│ 36ms (T- 4982ms): dig +norecurse @ns1.google.com. google.com. TXT # rmsg: NOERROR Answer: 6 NS: 0 Extra: 0
╰─── 54ms: resolve("google.com.", "TXT", 1) # [10]RR = TXT(google.com.)=google-site-verification=wD8N7i1JTNTkezJ49swvWW48f8_9xveREV4oB-0Hf5o TXT(google.com.)=MS=E4A68B9AB2BB9670BCE15412F62916164C0B20BB ...
TXT google-site-verification=wD8N7i1JTNTkezJ49swvWW48f8_9xveREV4oB-0Hf5o
TXT MS=E4A68B9AB2BB9670BCE15412F62916164C0B20BB
TXT facebook-domain-verification=22rm551cu4k0ab0bxsw536tlds4h95
TXT globalsign-smime-dv=CDYX+XFHUw2wml6/Gb8+59BsH31KzUr6c1l2BPvqKX8=
TXT docusign=1b0a6754-49b1-4db5-8540-d2c12664b289
TXT apple-domain-verification=30afIBcvSuDV2PLX
NS ns2.google.com.
NS ns1.google.com.
NS ns3.google.com.
NS ns4.google.com.
but if i try dig i get a lot more TXT records
> dig +norecurse +short @ns2.google.com. google.com. TXT
"docusign=05958488-4752-4ef2-95eb-aa7ba8a3bd0e"
"docusign=1b0a6754-49b1-4db5-8540-d2c12664b289"
"globalsign-smime-dv=CDYX+XFHUw2wml6/Gb8+59BsH31KzUr6c1l2BPvqKX8="
"MS=E4A68B9AB2BB9670BCE15412F62916164C0B20BB"
"webexdomainverification.8YX6G=6e6922db-e3e6-4a36-904e-a805c28087fa"
"facebook-domain-verification=22rm551cu4k0ab0bxsw536tlds4h95"
"google-site-verification=wD8N7i1JTNTkezJ49swvWW48f8_9xveREV4oB-0Hf5o"
"atlassian-domain-verification=5YjTmWmjI92ewqkx2oXmBaD60Td9zWon9r6eakvHX6B77zzkFQto8PQ9QsKnbf4I"
"v=spf1 include:_spf.google.com ~all"
"apple-domain-verification=30afIBcvSuDV2PLX"
"google-site-verification=TV9-DBe4R80X4v0M4U_bd_J9cpOJM0nikft0jAgjmsQ"
"onetrust-domain-verification=de01ed21f2fa4d8781cbc3ffb89cf4ef"
I also tried with cloudflare.com.
it should have a bunch of TXT records but dnsr returns 0 TXT records.
When cache expiration is enabled, the get() method may delete cache entries .
This could lead to a panic , since the get() method uses an RLock , allowing other goroutines to iterate the map while the deletion takes place.
I'm evaluating this for possible use in another project. It seems to be the nicest resolver available, but I need something with an expiring cache that respects TTL.
Would the team consider a PR to support TTL?
If a server is doing a recursion, asks for a record type that is not CNAME, but gets a CNAME response, then it should restart the query with the name from the CNAME record, merge the response from the restarted query with the CNAME response and return the combined response to whoever it was doing the recursion for.
example:
➜ ~ dig @127.0.0.1 -p 5000 +tcp translate.google.com A
; <<>> DiG 9.18.25 <<>> @127.0.0.1 -p 5000 +tcp translate.google.com A
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41052
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;translate.google.com. IN A
;; ANSWER SECTION:
translate.google.com. 300 IN CNAME www3.l.google.com.
I want in the response also the IP for A type:
www3.l.google.com. 300 IN A 172.217.18.206
…so that Dependabot will pick up new versions.
Use case is a web server with many public IP addresses and you need to specify exactly one specific to access the internet.
This test started failing a few days ago:
func TestHerokuA(t *testing.T) {
r := New(0)
rrs, err := r.ResolveErr("us-east-1-a.route.herokuapp.com", "A")
st.Expect(t, err, nil)
st.Expect(t, count(rrs, func(rr RR) bool { return rr.Type == "A" }) >= 1, true)
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.