mirror of
https://github.com/safing/portmaster
synced 2025-09-01 10:09:11 +00:00
Merge pull request #279 from safing/fix/resolver-unfailing
Improve resolver unfailing
This commit is contained in:
commit
909c7a031c
7 changed files with 61 additions and 8 deletions
|
@ -174,7 +174,7 @@ The format is: "protocol://ip:port?parameter=value¶meter=value"
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
nameserverRetryRate = config.Concurrent.GetAsInt(CfgOptionNameserverRetryRateKey, 600)
|
||||
nameserverRetryRate = config.Concurrent.GetAsInt(CfgOptionNameserverRetryRateKey, 300)
|
||||
|
||||
err = config.Register(&config.Option{
|
||||
Name: "Ignore System/Network Servers",
|
||||
|
|
|
@ -377,6 +377,10 @@ resolveLoop:
|
|||
if rrCache.RCode != dns.RcodeSuccess && tryAll {
|
||||
continue
|
||||
}
|
||||
|
||||
// Report a successful connection.
|
||||
resolver.Conn.ResetFailure()
|
||||
|
||||
break resolveLoop
|
||||
}
|
||||
}
|
||||
|
|
|
@ -124,3 +124,5 @@ func (er *envResolverConn) ReportFailure() {}
|
|||
func (er *envResolverConn) IsFailing() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (er *envResolverConn) ResetFailure() {}
|
||||
|
|
|
@ -54,6 +54,8 @@ func (mrc *mDNSResolverConn) IsFailing() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (mrc *mDNSResolverConn) ResetFailure() {}
|
||||
|
||||
type savedQuestion struct {
|
||||
question dns.Question
|
||||
expires time.Time
|
||||
|
|
|
@ -24,11 +24,13 @@ type PlainResolver struct {
|
|||
|
||||
// NewPlainResolver returns a new TPCResolver.
|
||||
func NewPlainResolver(resolver *Resolver) *PlainResolver {
|
||||
return &PlainResolver{
|
||||
newResolver := &PlainResolver{
|
||||
BasicResolverConn: BasicResolverConn{
|
||||
resolver: resolver,
|
||||
},
|
||||
}
|
||||
newResolver.BasicResolverConn.init()
|
||||
return newResolver
|
||||
}
|
||||
|
||||
// Query executes the given query against the resolver.
|
||||
|
|
|
@ -62,7 +62,7 @@ func (ifq *InFlightQuery) MakeCacheRecord(reply *dns.Msg) *RRCache {
|
|||
// NewTCPResolver returns a new TPCResolver.
|
||||
func NewTCPResolver(resolver *Resolver) *TCPResolver {
|
||||
var instanceID uint32
|
||||
return &TCPResolver{
|
||||
newResolver := &TCPResolver{
|
||||
BasicResolverConn: BasicResolverConn{
|
||||
resolver: resolver,
|
||||
},
|
||||
|
@ -79,6 +79,8 @@ func NewTCPResolver(resolver *Resolver) *TCPResolver {
|
|||
queries: make(chan *dns.Msg, 1000),
|
||||
inFlightQueries: make(map[uint16]*InFlightQuery),
|
||||
}
|
||||
newResolver.BasicResolverConn.init()
|
||||
return newResolver
|
||||
}
|
||||
|
||||
// UseTLS enabled TLS for the TCPResolver. TLS settings must be correctly configured in the Resolver.
|
||||
|
|
|
@ -8,6 +8,9 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"github.com/tevino/abool"
|
||||
|
||||
"github.com/safing/portbase/utils"
|
||||
"github.com/safing/portmaster/netenv"
|
||||
"github.com/safing/portmaster/network/netutils"
|
||||
)
|
||||
|
@ -179,16 +182,27 @@ type ResolverConn interface { //nolint:go-lint // TODO
|
|||
Query(ctx context.Context, q *Query) (*RRCache, error)
|
||||
ReportFailure()
|
||||
IsFailing() bool
|
||||
ResetFailure()
|
||||
}
|
||||
|
||||
// BasicResolverConn implements ResolverConn for standard dns clients.
|
||||
type BasicResolverConn struct {
|
||||
sync.Mutex // for lastFail
|
||||
sync.Mutex // Also used by inheriting structs.
|
||||
|
||||
resolver *Resolver
|
||||
|
||||
failing *abool.AtomicBool
|
||||
failingUntil time.Time
|
||||
fails int
|
||||
failLock sync.Mutex
|
||||
|
||||
networkChangedFlag *utils.Flag
|
||||
}
|
||||
|
||||
// init initializes the basic resolver connection.
|
||||
func (brc *BasicResolverConn) init() {
|
||||
brc.failing = abool.New()
|
||||
brc.networkChangedFlag = netenv.GetNetworkChangedFlag()
|
||||
}
|
||||
|
||||
// ReportFailure reports that an error occurred with this resolver.
|
||||
|
@ -198,20 +212,47 @@ func (brc *BasicResolverConn) ReportFailure() {
|
|||
return
|
||||
}
|
||||
|
||||
brc.Lock()
|
||||
defer brc.Unlock()
|
||||
brc.failLock.Lock()
|
||||
defer brc.failLock.Unlock()
|
||||
|
||||
brc.fails++
|
||||
if brc.fails > FailThreshold {
|
||||
brc.failing.Set()
|
||||
brc.failingUntil = time.Now().Add(time.Duration(nameserverRetryRate()) * time.Second)
|
||||
brc.fails = 0
|
||||
|
||||
// Refresh the network changed flag in order to only regard changes after
|
||||
// the fail.
|
||||
brc.networkChangedFlag.Refresh()
|
||||
}
|
||||
}
|
||||
|
||||
// IsFailing returns if this resolver is currently failing.
|
||||
func (brc *BasicResolverConn) IsFailing() bool {
|
||||
brc.Lock()
|
||||
defer brc.Unlock()
|
||||
// Check if not failing.
|
||||
if !brc.failing.IsSet() {
|
||||
return false
|
||||
}
|
||||
|
||||
brc.failLock.Lock()
|
||||
defer brc.failLock.Unlock()
|
||||
|
||||
// Reset failure status if the network changed since the last query.
|
||||
if brc.networkChangedFlag.IsSet() {
|
||||
brc.networkChangedFlag.Refresh()
|
||||
brc.ResetFailure()
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if we are still
|
||||
return time.Now().Before(brc.failingUntil)
|
||||
}
|
||||
|
||||
// ResetFailure resets the failure status.
|
||||
func (brc *BasicResolverConn) ResetFailure() {
|
||||
if brc.failing.SetToIf(true, false) {
|
||||
brc.failLock.Lock()
|
||||
defer brc.failLock.Unlock()
|
||||
brc.fails = 0
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue