mirror of
https://github.com/tailscale/tailscale.git
synced 2024-12-12 19:24:40 +00:00
net/dnscache: add a bunch of synthetic failure knobs
This commit is contained in:
parent
6f700925ce
commit
a37032932f
@ -15,6 +15,7 @@
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -108,6 +109,11 @@ func (r *Resolver) ttl() time.Duration {
|
|||||||
// If err is nil, ip will be non-nil. The v6 address may be nil even
|
// If err is nil, ip will be non-nil. The v6 address may be nil even
|
||||||
// with a nil error.
|
// with a nil error.
|
||||||
func (r *Resolver) LookupIP(ctx context.Context, host string) (ip, v6 net.IP, allIPs []net.IPAddr, err 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 ip := net.ParseIP(host); ip != nil {
|
||||||
if ip4 := ip.To4(); ip4 != nil {
|
if ip4 := ip.To4(); ip4 != nil {
|
||||||
return ip4, nil, []net.IPAddr{{IP: ip4}}, nil
|
return ip4, nil, []net.IPAddr{{IP: ip4}}, nil
|
||||||
@ -266,6 +272,7 @@ func (r *Resolver) addIPCache(host string, ip, ip6 net.IP, allIPs []net.IPAddr,
|
|||||||
if r.ipCache == nil {
|
if r.ipCache == nil {
|
||||||
r.ipCache = make(map[string]ipCacheEntry)
|
r.ipCache = make(map[string]ipCacheEntry)
|
||||||
}
|
}
|
||||||
|
if false { // DEBUG DEBUG
|
||||||
r.ipCache[host] = ipCacheEntry{
|
r.ipCache[host] = ipCacheEntry{
|
||||||
ip: ip,
|
ip: ip,
|
||||||
ip6: ip6,
|
ip6: ip6,
|
||||||
@ -273,6 +280,7 @@ func (r *Resolver) addIPCache(host string, ip, ip6 net.IP, allIPs []net.IPAddr,
|
|||||||
expires: time.Now().Add(d),
|
expires: time.Now().Add(d),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type DialContextFunc func(ctx context.Context, network, address string) (net.Conn, error)
|
type DialContextFunc func(ctx context.Context, network, address string) (net.Conn, error)
|
||||||
|
|
||||||
@ -369,12 +377,30 @@ type dialCall struct {
|
|||||||
// dnsWasTrustworthy reports whether we think the IP address(es) we
|
// dnsWasTrustworthy reports whether we think the IP address(es) we
|
||||||
// tried (and failed) to dial were probably the correct IPs. Currently
|
// tried (and failed) to dial were probably the correct IPs. Currently
|
||||||
// the heuristic is whether they ever worked previously.
|
// the heuristic is whether they ever worked previously.
|
||||||
func (dc *dialCall) dnsWasTrustworthy() bool {
|
func (dc *dialCall) dnsWasTrustworthy() (ret bool) {
|
||||||
dc.d.mu.Lock()
|
dc.d.mu.Lock()
|
||||||
defer dc.d.mu.Unlock()
|
defer dc.d.mu.Unlock()
|
||||||
dc.mu.Lock()
|
dc.mu.Lock()
|
||||||
defer dc.mu.Unlock()
|
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 {
|
if len(dc.fails) == 0 {
|
||||||
// No information.
|
// No information.
|
||||||
return false
|
return false
|
||||||
@ -384,14 +410,30 @@ func (dc *dialCall) dnsWasTrustworthy() bool {
|
|||||||
// this dialer, assume the DNS is fine.
|
// this dialer, assume the DNS is fine.
|
||||||
for ip := range dc.fails {
|
for ip := range dc.fails {
|
||||||
if _, ok := dc.d.pastConnect[ip]; ok {
|
if _, ok := dc.d.pastConnect[ip]; ok {
|
||||||
|
if debug {
|
||||||
|
log.Printf("dnscache: DNS trustworthy due to past connection to %v", ip)
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dc *dialCall) dialOne(ctx context.Context, ip netaddr.IP) (net.Conn, error) {
|
func fileExists(path string) bool {
|
||||||
c, err := dc.d.fwd(ctx, dc.network, net.JoinHostPort(ip.String(), dc.port))
|
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)
|
dc.noteDialResult(ip, err)
|
||||||
return c, err
|
return c, err
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,6 @@ pkgs.mkShell {
|
|||||||
# - gopls, the language server for Go to increase editor integration
|
# - gopls, the language server for Go to increase editor integration
|
||||||
# - git, the version control program (used in some scripts)
|
# - git, the version control program (used in some scripts)
|
||||||
buildInputs = with pkgs; [
|
buildInputs = with pkgs; [
|
||||||
go goimports gopls git
|
go gopls git
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user