mirror of
https://github.com/safing/portmaster
synced 2025-09-04 11:39:29 +00:00
Merge pull request #585 from safing/fix/dns-cache-invalidation
Clear DNS cache when DNS resolver config changes and update resolver config
This commit is contained in:
commit
fca92a70f2
4 changed files with 42 additions and 21 deletions
|
@ -12,7 +12,7 @@ func registerAPI() error {
|
||||||
Path: "dns/clear",
|
Path: "dns/clear",
|
||||||
Write: api.PermitUser,
|
Write: api.PermitUser,
|
||||||
BelongsTo: module,
|
BelongsTo: module,
|
||||||
ActionFunc: clearNameCache,
|
ActionFunc: clearNameCacheHandler,
|
||||||
Name: "Clear cached DNS records",
|
Name: "Clear cached DNS records",
|
||||||
Description: "Deletes all saved DNS records from the database.",
|
Description: "Deletes all saved DNS records from the database.",
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
|
|
@ -31,7 +31,7 @@ var (
|
||||||
|
|
||||||
// Cloudflare (encrypted DNS, with malware protection)
|
// Cloudflare (encrypted DNS, with malware protection)
|
||||||
`dot://1.1.1.2:853?verify=cloudflare-dns.com&name=Cloudflare&blockedif=zeroip`,
|
`dot://1.1.1.2:853?verify=cloudflare-dns.com&name=Cloudflare&blockedif=zeroip`,
|
||||||
// `dot://1.0.0.2:853?verify=cloudflare-dns.com&name=Cloudflare&blockedif=zeroip`,
|
`dot://1.0.0.2:853?verify=cloudflare-dns.com&name=Cloudflare&blockedif=zeroip`,
|
||||||
|
|
||||||
// AdGuard (encrypted DNS, default flavor)
|
// AdGuard (encrypted DNS, default flavor)
|
||||||
// `dot://94.140.14.14:853?verify=dns.adguard.com&name=AdGuard&blockedif=zeroip`,
|
// `dot://94.140.14.14:853?verify=dns.adguard.com&name=AdGuard&blockedif=zeroip`,
|
||||||
|
@ -107,8 +107,9 @@ The format is: "protocol://ip:port?parameter=value¶meter=value"
|
||||||
- "search": specify prioritized domains/TLDs for this resolver (delimited by ",")
|
- "search": specify prioritized domains/TLDs for this resolver (delimited by ",")
|
||||||
- "search-only": use this resolver for domains in the "search" parameter only (no value)
|
- "search-only": use this resolver for domains in the "search" parameter only (no value)
|
||||||
`, `"`, "`"),
|
`, `"`, "`"),
|
||||||
|
Sensitive: true,
|
||||||
OptType: config.OptTypeStringArray,
|
OptType: config.OptTypeStringArray,
|
||||||
ExpertiseLevel: config.ExpertiseLevelExpert,
|
ExpertiseLevel: config.ExpertiseLevelUser,
|
||||||
ReleaseLevel: config.ReleaseLevelStable,
|
ReleaseLevel: config.ReleaseLevelStable,
|
||||||
DefaultValue: defaultNameServers,
|
DefaultValue: defaultNameServers,
|
||||||
ValidationRegex: fmt.Sprintf("^(%s|%s|%s)://.*", ServerTypeDoT, ServerTypeDNS, ServerTypeTCP),
|
ValidationRegex: fmt.Sprintf("^(%s|%s|%s)://.*", ServerTypeDoT, ServerTypeDNS, ServerTypeTCP),
|
||||||
|
@ -118,6 +119,14 @@ The format is: "protocol://ip:port?parameter=value¶meter=value"
|
||||||
config.DisplayOrderAnnotation: cfgOptionNameServersOrder,
|
config.DisplayOrderAnnotation: cfgOptionNameServersOrder,
|
||||||
config.CategoryAnnotation: "Servers",
|
config.CategoryAnnotation: "Servers",
|
||||||
config.QuickSettingsAnnotation: []config.QuickSetting{
|
config.QuickSettingsAnnotation: []config.QuickSetting{
|
||||||
|
{
|
||||||
|
Name: "Cloudflare (with Malware Filter)",
|
||||||
|
Action: config.QuickReplace,
|
||||||
|
Value: []string{
|
||||||
|
"dot://1.1.1.2:853?verify=cloudflare-dns.com&name=Cloudflare&blockedif=zeroip",
|
||||||
|
"dot://1.0.0.2:853?verify=cloudflare-dns.com&name=Cloudflare&blockedif=zeroip",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "Quad9",
|
Name: "Quad9",
|
||||||
Action: config.QuickReplace,
|
Action: config.QuickReplace,
|
||||||
|
@ -142,14 +151,6 @@ The format is: "protocol://ip:port?parameter=value¶meter=value"
|
||||||
"dot://94.130.106.88:443?verify=dot1.applied-privacy.net&name=AppliedPrivacy",
|
"dot://94.130.106.88:443?verify=dot1.applied-privacy.net&name=AppliedPrivacy",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Name: "Cloudflare (with Malware Filter)",
|
|
||||||
Action: config.QuickReplace,
|
|
||||||
Value: []string{
|
|
||||||
"dot://1.1.1.2:853?verify=cloudflare-dns.com&name=Cloudflare&blockedif=zeroip",
|
|
||||||
"dot://1.0.0.2:853?verify=cloudflare-dns.com&name=Cloudflare&blockedif=zeroip",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
"self:detail:internalSpecialUseDomains": internalSpecialUseDomains,
|
"self:detail:internalSpecialUseDomains": internalSpecialUseDomains,
|
||||||
"self:detail:connectivityDomains": netenv.ConnectivityDomains,
|
"self:detail:connectivityDomains": netenv.ConnectivityDomains,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package resolver
|
package resolver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -129,13 +130,18 @@ func (nameRecord *NameRecord) Save() error {
|
||||||
return recordDatabase.PutNew(nameRecord)
|
return recordDatabase.PutNew(nameRecord)
|
||||||
}
|
}
|
||||||
|
|
||||||
// clearNameCache clears all dns caches from the database.
|
// clearNameCacheHandler is an API handler that clears all dns caches from the database.
|
||||||
func clearNameCache(ar *api.Request) (msg string, err error) {
|
func clearNameCacheHandler(ar *api.Request) (msg string, err error) {
|
||||||
log.Info("resolver: user requested dns cache clearing via action")
|
log.Info("resolver: user requested dns cache clearing via action")
|
||||||
|
|
||||||
|
return clearNameCache(ar.Context())
|
||||||
|
}
|
||||||
|
|
||||||
|
// clearNameCache clears all dns caches from the database.
|
||||||
|
func clearNameCache(ctx context.Context) (msg string, err error) {
|
||||||
recordDatabase.FlushCache()
|
recordDatabase.FlushCache()
|
||||||
recordDatabase.ClearCache()
|
recordDatabase.ClearCache()
|
||||||
n, err := recordDatabase.Purge(ar.Context(), query.New(nameRecordsKeyPrefix))
|
n, err := recordDatabase.Purge(ctx, query.New(nameRecordsKeyPrefix))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package resolver
|
package resolver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -39,6 +40,7 @@ var (
|
||||||
systemResolvers []*Resolver // all resolvers that were assigned by the system
|
systemResolvers []*Resolver // all resolvers that were assigned by the system
|
||||||
localScopes []*Scope // list of scopes with a list of local resolvers that can resolve the scope
|
localScopes []*Scope // list of scopes with a list of local resolvers that can resolve the scope
|
||||||
activeResolvers map[string]*Resolver // lookup map of all resolvers
|
activeResolvers map[string]*Resolver // lookup map of all resolvers
|
||||||
|
currentResolverConfig []string // current active resolver config, to detect changes
|
||||||
resolversLock sync.RWMutex
|
resolversLock sync.RWMutex
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -285,8 +287,20 @@ func loadResolvers() {
|
||||||
// Resolve module error about missing resolvers.
|
// Resolve module error about missing resolvers.
|
||||||
module.Resolve(missingResolversErrorID)
|
module.Resolve(missingResolversErrorID)
|
||||||
|
|
||||||
|
// Check if settings were changed and clear name cache when they did.
|
||||||
|
newResolverConfig := configuredNameServers()
|
||||||
|
if len(currentResolverConfig) > 0 &&
|
||||||
|
!utils.StringSliceEqual(currentResolverConfig, newResolverConfig) {
|
||||||
|
module.StartWorker("clear dns cache", func(ctx context.Context) error {
|
||||||
|
log.Info("resolver: clearing dns cache due to changed resolver config")
|
||||||
|
_, err := clearNameCache(ctx)
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
}
|
||||||
|
currentResolverConfig = newResolverConfig
|
||||||
|
|
||||||
newResolvers := append(
|
newResolvers := append(
|
||||||
getConfiguredResolvers(configuredNameServers()),
|
getConfiguredResolvers(newResolverConfig),
|
||||||
getSystemResolvers()...,
|
getSystemResolvers()...,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue