mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-19 08:46:38 +00:00
Apply DNS host config on change only (#4695)
Adds a per-instance uint64 hash to DefaultServer to detect identical merged host DNS configs (including extra domains). applyHostConfig computes and compares the hash, skips applying if unchanged, treats hash errors as a fail-safe (proceed to apply), and updates the stored hash only after successful hashing and apply.
This commit is contained in:
@@ -80,6 +80,7 @@ type DefaultServer struct {
|
|||||||
updateSerial uint64
|
updateSerial uint64
|
||||||
previousConfigHash uint64
|
previousConfigHash uint64
|
||||||
currentConfig HostDNSConfig
|
currentConfig HostDNSConfig
|
||||||
|
currentConfigHash uint64
|
||||||
handlerChain *HandlerChain
|
handlerChain *HandlerChain
|
||||||
extraDomains map[domain.Domain]int
|
extraDomains map[domain.Domain]int
|
||||||
|
|
||||||
@@ -207,6 +208,7 @@ func newDefaultServer(
|
|||||||
hostsDNSHolder: newHostsDNSHolder(),
|
hostsDNSHolder: newHostsDNSHolder(),
|
||||||
hostManager: &noopHostConfigurator{},
|
hostManager: &noopHostConfigurator{},
|
||||||
mgmtCacheResolver: mgmtCacheResolver,
|
mgmtCacheResolver: mgmtCacheResolver,
|
||||||
|
currentConfigHash: ^uint64(0), // Initialize to max uint64 to ensure first config is always applied
|
||||||
}
|
}
|
||||||
|
|
||||||
// register with root zone, handler chain takes care of the routing
|
// register with root zone, handler chain takes care of the routing
|
||||||
@@ -586,8 +588,29 @@ func (s *DefaultServer) applyHostConfig() {
|
|||||||
|
|
||||||
log.Debugf("extra match domains: %v", maps.Keys(s.extraDomains))
|
log.Debugf("extra match domains: %v", maps.Keys(s.extraDomains))
|
||||||
|
|
||||||
|
hash, err := hashstructure.Hash(config, hashstructure.FormatV2, &hashstructure.HashOptions{
|
||||||
|
ZeroNil: true,
|
||||||
|
IgnoreZeroValue: true,
|
||||||
|
SlicesAsSets: true,
|
||||||
|
UseStringer: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Warnf("unable to hash the host dns configuration, will apply config anyway: %s", err)
|
||||||
|
// Fall through to apply config anyway (fail-safe approach)
|
||||||
|
} else if s.currentConfigHash == hash {
|
||||||
|
log.Debugf("not applying host config as there are no changes")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("applying host config as there are changes")
|
||||||
if err := s.hostManager.applyDNSConfig(config, s.stateManager); err != nil {
|
if err := s.hostManager.applyDNSConfig(config, s.stateManager); err != nil {
|
||||||
log.Errorf("failed to apply DNS host manager update: %v", err)
|
log.Errorf("failed to apply DNS host manager update: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only update hash if it was computed successfully and config was applied
|
||||||
|
if err == nil {
|
||||||
|
s.currentConfigHash = hash
|
||||||
}
|
}
|
||||||
|
|
||||||
s.registerFallback(config)
|
s.registerFallback(config)
|
||||||
|
|||||||
@@ -1602,7 +1602,10 @@ func TestExtraDomains(t *testing.T) {
|
|||||||
"other.example.com.",
|
"other.example.com.",
|
||||||
"duplicate.example.com.",
|
"duplicate.example.com.",
|
||||||
},
|
},
|
||||||
applyHostConfigCall: 4,
|
// Expect 3 calls instead of 4 because when deregistering duplicate.example.com,
|
||||||
|
// the domain remains in the config (ref count goes from 2 to 1), so the host
|
||||||
|
// config hash doesn't change and applyDNSConfig is not called.
|
||||||
|
applyHostConfigCall: 3,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Config update with new domains after registration",
|
name: "Config update with new domains after registration",
|
||||||
@@ -1657,7 +1660,10 @@ func TestExtraDomains(t *testing.T) {
|
|||||||
expectedMatchOnly: []string{
|
expectedMatchOnly: []string{
|
||||||
"extra.example.com.",
|
"extra.example.com.",
|
||||||
},
|
},
|
||||||
applyHostConfigCall: 3,
|
// Expect 2 calls instead of 3 because when deregistering protected.example.com,
|
||||||
|
// it's removed from extraDomains but still remains in the config (from customZones),
|
||||||
|
// so the host config hash doesn't change and applyDNSConfig is not called.
|
||||||
|
applyHostConfigCall: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Register domain that is part of nameserver group",
|
name: "Register domain that is part of nameserver group",
|
||||||
|
|||||||
Reference in New Issue
Block a user