summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrew Dunham <andrew@du.nham.ca>2022-09-02 12:06:25 -0400
committerAndrew Dunham <andrew@tailscale.com>2022-09-02 13:22:36 -0400
commita37032932fb73e5b674c37988383d31d89e761ee (patch)
treefee551b4045f2d574bfe812fc13649177048cf01
parent6f700925cef22d8b2a100840c8d9eb084dadfece (diff)
downloadtailscale-andrew/dnscache-debugging-1.22.2.tar.xz
tailscale-andrew/dnscache-debugging-1.22.2.zip
net/dnscache: add a bunch of synthetic failure knobsandrew/dnscache-debugging-1.22.2
-rw-r--r--net/dnscache/dnscache.go58
-rw-r--r--shell.nix2
2 files changed, 51 insertions, 9 deletions
diff --git a/net/dnscache/dnscache.go b/net/dnscache/dnscache.go
index cf1ef5817..b84579287 100644
--- a/net/dnscache/dnscache.go
+++ b/net/dnscache/dnscache.go
@@ -15,6 +15,7 @@ import (
"fmt"
"log"
"net"
+ "os"
"runtime"
"sync"
"time"
@@ -108,6 +109,11 @@ var debug = envknob.Bool("TS_DEBUG_DNS_CACHE")
// If err is nil, ip will be non-nil. The v6 address may be nil even
// with a nil error.
func (r *Resolver) LookupIP(ctx context.Context, host string) (ip, v6 net.IP, allIPs []net.IPAddr, err error) {
+ if fileExists("/tmp/dnscache-synthetic-resolve-failure.txt") {
+ log.Printf("dnscache: synthetic resolve failure for %s", host)
+ return nil, nil, nil, fmt.Errorf("synthetic resolve failure for %s", host)
+ }
+
if ip := net.ParseIP(host); ip != nil {
if ip4 := ip.To4(); ip4 != nil {
return ip4, nil, []net.IPAddr{{IP: ip4}}, nil
@@ -266,11 +272,13 @@ func (r *Resolver) addIPCache(host string, ip, ip6 net.IP, allIPs []net.IPAddr,
if r.ipCache == nil {
r.ipCache = make(map[string]ipCacheEntry)
}
- r.ipCache[host] = ipCacheEntry{
- ip: ip,
- ip6: ip6,
- allIPs: allIPs,
- expires: time.Now().Add(d),
+ if false { // DEBUG DEBUG
+ r.ipCache[host] = ipCacheEntry{
+ ip: ip,
+ ip6: ip6,
+ allIPs: allIPs,
+ expires: time.Now().Add(d),
+ }
}
}
@@ -369,12 +377,30 @@ type dialCall struct {
// dnsWasTrustworthy reports whether we think the IP address(es) we
// tried (and failed) to dial were probably the correct IPs. Currently
// the heuristic is whether they ever worked previously.
-func (dc *dialCall) dnsWasTrustworthy() bool {
+func (dc *dialCall) dnsWasTrustworthy() (ret bool) {
dc.d.mu.Lock()
defer dc.d.mu.Unlock()
dc.mu.Lock()
defer dc.mu.Unlock()
+ defer func() {
+ log.Printf("dnscache: dnsWasTrustworthy = %v", ret)
+ }()
+
+ // DEBUG DEBUG DEBUG
+ if fileExists("/tmp/dnscache-drop-fails.txt") {
+ log.Printf("dnscache: clearing failed list")
+ dc.fails = map[netaddr.IP]error{}
+ }
+ if fileExists("/tmp/dnscache-drop-pastconnect.txt") {
+ log.Printf("dnscache: clearing past connections list")
+ dc.d.pastConnect = map[netaddr.IP]time.Time{}
+ }
+
+ if debug {
+ log.Printf("dnscache: we have %d failures and %d past connections", len(dc.fails), len(dc.d.pastConnect))
+ }
+
if len(dc.fails) == 0 {
// No information.
return false
@@ -384,14 +410,30 @@ func (dc *dialCall) dnsWasTrustworthy() bool {
// this dialer, assume the DNS is fine.
for ip := range dc.fails {
if _, ok := dc.d.pastConnect[ip]; ok {
+ if debug {
+ log.Printf("dnscache: DNS trustworthy due to past connection to %v", ip)
+ }
return true
}
}
return false
}
-func (dc *dialCall) dialOne(ctx context.Context, ip netaddr.IP) (net.Conn, error) {
- c, err := dc.d.fwd(ctx, dc.network, net.JoinHostPort(ip.String(), dc.port))
+func fileExists(path string) bool {
+ st, err := os.Stat(path)
+ if err != nil {
+ return false
+ }
+ return st.Mode().IsRegular()
+}
+
+func (dc *dialCall) dialOne(ctx context.Context, ip netaddr.IP) (c net.Conn, err error) {
+ if fileExists("/tmp/dnscache-synthetic-dial-failure.txt") {
+ log.Printf("dnscache: synthetic dial failure for %s", ip)
+ err = fmt.Errorf("synthetic dial failure for %s", ip)
+ } else {
+ c, err = dc.d.fwd(ctx, dc.network, net.JoinHostPort(ip.String(), dc.port))
+ }
dc.noteDialResult(ip, err)
return c, err
}
diff --git a/shell.nix b/shell.nix
index 273ecf9b6..072eee1f9 100644
--- a/shell.nix
+++ b/shell.nix
@@ -19,6 +19,6 @@ pkgs.mkShell {
# - gopls, the language server for Go to increase editor integration
# - git, the version control program (used in some scripts)
buildInputs = with pkgs; [
- go goimports gopls git
+ go gopls git
];
}